OmniAICreator/Qiita-1.07M huggingface dataset:
RailsにおけるCache戦略について（低レベルキャッシュ）

ここでは、[低レベルキャッシュ](https://railsguides.jp/caching_with_rails.html#%E4%BD%8E%E3%83%AC%E3%83%99%E3%83%AB%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5)（特定の値やクエリ結果をキャッシュする）についてまとめています。

# 注意： 時間の経過とともにレスポンスが変化するデータのキャッシュについて

時間の経過とともにレスポンスが変わるものをキャッシュする場合は、有効期間（`expires_in`）を指定して、一定時間後にキャッシュが無効になるようにする必要があります。

キャッシュには`キャッシュキー`を指定しますが、レコードが変更された際にこのキーも更新されることで、キャッシュが更新されます。
しかし、例えば`Coupon.where('expired_at > ?', Time.current)`（有効なクーポンを返す）の場合、レコードの内容は変わらなくても時間の経過とともにレスポンスが変わることが期待されます。有効期限を設定せずにキャッシュを使った場合、レコードの内容が変わらなければ`キャッシュキー`も更新されないため、永久にキャッシュが更新されないという状況になります。
キャッシュの有効期限（`expires_in`)を設定するようにしましょう。

尚、`expires_in`は、キャッシュが作られてからの期間です。

# はじめに覚えておくこと

- `Rails.cache.fetch` このメソッドで、キャッシュのread/writeが両方出来る。
- `<cache_key>` 後述の通り、基本的にRailsが用意しているものを使う。
- `expires_in` キャッシュの有効期限を指定する。

# 実装例

```ruby
Rails.cache.fetch(<cache_key>, expires_in: 3.hours) do
  ...  
  キャッシュが無かった場合、ここで指定した処理が実行され、結果が返されるとともに、
  <cache_key> で指定したキーを使ってキャッシュされる
  ...
end
```

# キャッシュキーの例
## `cache_key_with_version`（単一レコードに対するキー）
- 以下の通り、「モデルのクラス名」、「id」、「updated_at」を元に生成される。
 
```ruby
> coupon.cache_key_with_version
=> "coupons/1-20191011041439715799"
```

```ruby
class Product < ApplicationRecord
  def competing_price
    Rails.cache.fetch("#{cache_key_with_version}/competing_price", expires_in: 12.hours) do
      Competitor::API.find_price(id)
    end
  end
end
```

## [`cache_key`](https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb#L311)（複数レコードに対するキー）
- 以下の通り、「モデルのクラス名」、「query-」、「レコード数」、「updated_atの最大値」を元に生成される。
  
```ruby
> coupons.cache_key
   (5.9ms)  SELECT COUNT(*) AS "size", MAX("coupons"."updated_at") AS timestamp FROM "coupons"
=> "coupons/query-39c9e75f3c3df8d18398e78bc912b37c-6-20191011041439715799"

## テーブル全体を対象とする場合は以下の通り
> Coupon.all.cache_key
```

```ruby
class Product < ApplicationRecord
  def popular_products
    Rails.cache.fetch("#{Product.all.cache_key}", expires_in: 12.hours) do
      <do_something>
    end
  end
end
```

# ログ

### キャッシュ・ライト時のログ

```ruby
Cache write: channels/query-cce0a1bf6d4900cec9cf496202394b05-1-20191016105530000000
   (1.5ms)  SELECT COUNT(*) AS `size`, MAX(`catalogs`.`updated_at`) AS timestamp FROM `catalogs`
  ↳ app/controllers/toppage_controller.rb:27
```

### キャッシュ・リード（キャッシュ・ヒット）時のログ

```ruby
Cache read: catalogs/query-5bef3b48a20fab8e12bcfb3f222f834d-1-20191004025349000000
Cache fetch_hit: catalogs/query-5bef3b48a20fab8e12bcfb3f222f834d-1-20191004025349000000
```

# 備考

キャッシュはデフォルトではproduction環境でのみ有効です。
ローカルでキャッシュを使う場合は、対応する`config/environments/*.rb`ファイルで`config.action_controller.perform_caching`を`true`に設定する必要があります。
但し、ここで説明した「低レベルキャッシュ」の動作には影響しません。

> config.action_controller.perform_caching値の変更は、Action Controllerコンポーネントで提供されるキャッシュでのみ有効になります。つまり、後述する 低レベルキャッシュ の動作には影響しません。
>
> [railsguide.jp](https://railsguides.jp/caching_with_rails.html#%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5)より。
[Android] StatusBarManagerを使ったNotificationパネルのオンオフ方法

Androidアプリで[StatusBarManager](https://developer.android.com/reference/android/app/StatusBarManager)という非公開（API level 29から公式化?）のAPIを利用して、Notificationパネル（プッシュ通知一覧のやつ）の表示オンオフする方法を説明します。

### StatusBarManagerソースコード
StatusBarManagerのソースコードは[ここ](https://android.googlesource.com/platform/frameworks/base/+/android-4.3_r2.1/core/java/android/app/StatusBarManager.java)にあります。

### 必要なパーミッション
以下をAndroidManifest.xmlに追加する必要があります。runtimeパーミッションではないので、AndroidManifest.xmlに追加するだけでOKです。

```xml:AndroidManifest.xml
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>
```

### ソースコード
非公開扱いのクラスのため、何が起きてもいいようにtry/catchは入れておきましょう。パネルを開く場合は、android.app.StatusBarManager.expandNotificationsPanelをコールします。

```java:パネルを開くサンプル
if(ContextCompat.checkSelfPermission(this, Manifest.permission.EXPAND_STATUS_BAR) != PackageManager.PERMISSION_GRANTED)
    return;

try {
    Object service = getSystemService("statusbar");
    Class<?> statusBarManager = Class.forName("android.app.StatusBarManager");
    Method expand = statusBarManager.getMethod("expandNotificationsPanel");
    expand.invoke(service);
}
catch (Exception e){
    e.printStackTrace();
}
```

逆にパネルを閉じる場合は、クイック設定画面も同時に閉じる事になりますが、android.app.StatusBarManager.collapsePanelsをコールします。

```java:パネルを閉じるサンプル
if(ContextCompat.checkSelfPermission(this, Manifest.permission.EXPAND_STATUS_BAR) != PackageManager.PERMISSION_GRANTED)
    return;

try {
    Object service = getSystemService("statusbar");
    Class<?> statusBarManager = Class.forName("android.app.StatusBarManager");
    Method expand = statusBarManager.getMethod("collapsePanels");
    expand.invoke(service);
}
catch (Exception e){
    e.printStackTrace();
}
```
Pythonで動画の幅、高さ、fpsを取得、そこから1秒ごと（任意の間隔）に画像を生成する方法

#動画の各種情報を取得7

import cv2

video_path = '動画のパス'
cap = cv2.VideoCapture(video_path)

# 幅
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
# 高さ
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
# 総フレーム数
count = cap.get(cv2.CAP_PROP_FRAME_COUNT)
# fps
fps = cap.get(cv2.CAP_PROP_FPS)

print("width:{}, height:{}, count:{}, fps:{}".format(width,height,count,fps))


#1秒ごとに画像を生成

import cv2

video_path = "動画のパス"
cap = cv2.VideoCapture(video_path)

count = cap.get(cv2.CAP_PROP_FRAME_COUNT)
fps = cap.get(cv2.CAP_PROP_FPS)

print("width:{}, height:{}, count:{}, fps:{}".format(width,height,count,fps))

for num in range(1, int(count), int(fps)):
    cap.set(cv2.CAP_PROP_POS_FRAMES, num)
    cv2.imwrite("picture{:0=3}".format(int((num-1)/int(fps)))+".jpg", cap.read()[1])
    print("save picture{:0=3}".format(int((num-1)/int(fps)))+".jpg")

cap.release()
REST API利用時のNamespaceの重要性(RESTとGraphQLの比較とかも）

[「Railsで超簡単API」](https://qiita.com/k-penguin-sato/items/adba7a1a1ecc3582a9c9)というQiita記事でAPIの勉強をしていたところ、名前空間という概念が出てきたので、まとめました。

# Namespace(名前空間)とは
Namespaceとは名前の衝突を防ぐためにレイヤーを整理する概念のこと。Namespaceを使うと、名前が同じであっても、Namespaceが異なっていれば衝突が起きることがない。Namespaceは名字のようなもので、太郎という同じ名前の人間が二人いたとしても、山田太郎と上田太郎は名字が異なるため、概念の衝突を避けることが出来る。コードに起こすと下記のようなイメージ。

```ruby

namespace YAMADA
{
  name = "Taro"
}

namespace UEDA
{
 name = "Taro"
}

put YAMADA::name
 => Taro

put UEDA::name
 => Taro
```

最後の出力結果は同じでになるが、出力されたTaroの定義元を見ると、AとBという別々の場所から参照されている。また、Namespaceの内容を別空間から呼ぶ場合は出所も一緒に明示する必要がある。

# REST APIとGraphQLの特徴と相違点
## REST APIとは
外部からプログラムを呼び出す際の規約の一つで、下記の原則に乗っ取る。

1. ステートレスな管理(アクセス集中に耐えやすくするため）
2. 命令系統の事前定義（HTTPのGETやPOSTメソッドなど）
3. URLとメソッドでリソースを表現する
4. 情報の内部に、複数の情報へのリンクをもたせることが出来る

#GraphQLとは
Facebook社が開発するWebAPI規格。GithubやNetflix、Airbnbなどが採用していることで有名。「クエリ言語」と「スキーマ言語」から成る。

クエリ言語には以下の3種類がある。
1. データ取得系のquery
2. データ更新系のmutation
3. サーバーサイドのイベント通知のためのsubscription

スキーマ言語はGraphQLの仕様を記述するための言語。下記の様に、クエリの型を定義していく。

```graphql

type Query {
  currentUser: User!
}

type User {
  id: ID!
  name: String!
}
```

上記のようなスキーマに対して、下記のようなクエリを発行すると、JSON形式で内容が返ってくる。

```graphql

query GetCurrentUser {
  currentUser {
    id
    name
  }
}
```

GraphQLの主な特徴は大きく3つ。
1. クエリとレスポンスの構造の類似(GraphQLではJSONのなかの欲しいフィールドだけを指定することにより、レスポンスを軽くすることも可能)
2. スキーマファーストの思想
3. 単一エンドポイント

# REST APIとGraphQLの比較

### エンドポイントの数
RESTではエンドポイントが複数あるのに対し、GraphQLはエンドポイントが単一であることが特徴。RESTではURLにてエンドポイントを指定することで、リソースの明文化をすることが出来た。一方GraphQLは```("POST /graphql")```のような形で単一のエンドポイントだけが存在し、欲しいリソースはbodyの中に書く。

### URIやHTTPS構造の使い方
RESTはURIやHTTPSでアクセス先を明確化する一方、GraphQLでは問い合わせ言語とスキーマ言語でアクセス内容を明確化する。

### アクセス回数の制限
RESTではサーバー負荷の軽減の観点から1時間あたりのアクセス件数を制限するケースが多いが、GraphQLではこの制限がない。そのため、負荷の計算を自前で行う必要がある。

# REST APIにおいてNamespaceの設定が重要な理由
RESTはエンドポイントが複数あるため、APIのURIの設定をわかりやすくするためにNamespaceを設定すると良い。また、この際にディレクトリの構成もNamespaceの構成と統一してあげる必要がある。

```ruby
Rails.application.routes.draw do
  namespace 'api' do
    namespace 'v1' do
      resources :posts
    end
  end
end
```

このようなNamespaceの構造を作った場合、下記のようなディレクトリ構成を設定する。

```
---- controllers
      --- api
        -- v1
         - posts_controller.rb
```

ちなみにNamespaceを使わなくてもScopeで設定することも可能。
[【Ruby on Rails】ルーティング scope と namespace の違い](https://techblog.kyamanak.com/entry/2017/07/30/223113)
仙台CTF 2017 [Lab01] プロキシログの調査 100

#問題

http://ctf.sectanlab.jp/2017/challenges

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/4be46962-33fc-e38a-72f7-287989aac0e7.png)

#解いてみた

問題のファイルを見てみると一般的なログファイルでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/91d93746-8846-d526-aa49-d9f86332feb5.png)

grepで「c2.hacker.com」を抽出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/d8bb1825-5f9c-4383-2e85-cdf6880575ea.png)

1件だけだったのでこれが答えです。
仙台CTF 2017 [MalX] マルウェアの通信先（EXE編その２） 300

#問題

http://ctf.sectanlab.jp/2017/challenges

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/1242e1aa-03c0-b546-9b20-ec600262239c.png)

#解いてみた

この問題もexeファイルです。

bintextを使ってみましたが、今回はURLはべた書きはされていませんでした。

wiresharkを起動した状態で実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/0c40495e-919a-cd9a-d217-e3eb22cf16ab.png)

特に通信は発生せずに、コマンドプロンプトが立ち上がっただけでした。
問題文にあるように、何か条件が必要なようです。

ollydbg使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/744b0498-eef0-43e8-e091-276ab05c0125.png)

004011D3にくるとcmdに「Time will tell」が表示されてしまうので、そこを回避するようにジャンプ系の処理が来た時にZフラグを逆にして回避しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/e24fa1ea-2c62-d47b-f865-698cb3b4f860.png)

そうするとURLが出てきました。
これが答えでした。
Redux-saga のドキュメントにはない概念: multicast

Redux Saga のドキュメントを読んでいたけれども、 Channel 周りの記述で、どうも説明(ドキュメント)が足りないと思うことがあったので、その備忘録。

# 疑問

https://redux-saga.js.org/docs/advanced/Channels.html

Redux Saga のドキュメントには、上記の通り channel の使い方が書いてある。ここで説明されている channel は、どちらかというと queue のような振る舞いをする。

一方で、例えば [runSaga のドキュメント](https://redux-saga.js.org/docs/api/#runsagaoptions-saga-args) をみていると、 redux-saga 自体は、 redux store 以外にも接続しながら実行することができ、その input を司るのが `channel` パラメータであり、 output を司るのが `dispatch` のパラメータであることがみて取れる。

しかし、これはドキュメントだけを読んだ際の知識とは矛盾する。何かと言うと、 redux-saga において `take` を行う場合、それを行なっているすべての saga (rootSaga に合成されているすべての saga) は、単一の dispatch に対して、それぞれが結果の action を取得できる、という前提で進む。 channel が queue であった場合、これは何かがおかしい、という話になる。

# 回答

redux saga の channel には、普通の queue っぽい channel と、 subscribe / multi dispatch のような振る舞いをする channel がある。その実、ドキュメントの中で存在が言及されている `stdChannel` は、後者にあたる。

redux-saga をミドルウェアとして redux に接続した場合、 redux store から dispatch された action は、その実、 `stdChannel` に投入され、それに対してそれぞれの saga は take することになる。

ソースコード上は、 redux-saga の channel は multicast の概念を持っていて、それはソースコード上から確認できる https://github.com/redux-saga/redux-saga/blob/master/packages/core/src/internal/channel.js
Dockerと仮想マシンの違い

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている[箕牧和廣](https://qiita.com/mimaki_kazuhiro)です。
今回はDockerについて書いていこうと思います。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#Dockerとは
Dockerとは軽量な仮想化環境を実現するためのツールです。
Dockerを利用すればOSの内部に独立したアプリケーションの実行環境を構築することができます。この構築環境をコンテナと呼びます。

#コンテナ
コンテナ内のファイルシステムやリソースはベースOSと分離されており、コンテナ内は実行環境として独立しています。
コンテナを利用することで、1つのOS内に複数の実行環境を構築できます。

#イメージ
イメージとはコンテナを生成する元になるものです。同じイメージを使えば、同じ Linux ディストリビューションで同じアプリケーションがインストールされた全く同じ環境を複製することができます。
また、Dockerではイメージを編集し、イメージの機能・内容を継承することもできます。
Dockerイメージを使うことで、従来必要だったプログラミング言語のインストールやフレームワークのインストールといった手間がかからず、パソコンのプログラミング環境を汚すことなく様々なアプリ開発に即・挑戦できるという訳です。

#仮想マシン
仮想マシンとは仮想的にハードウェアを動作させることです。
仮想マシンには大きく分けて「ホスト型」と「ハイパーバイザー型」の２種類あります。

##ホスト型とハイパーバイザー型
ホスト型とは、OSに仮想化ソフトウェアをインストールし、その上で仮想マシンを動かすことです。既存のサーバーを使えるため、手軽に利用できる一方で、ハードウェアにアクセスする際OSを経由しなければいけません。
ハイパーバイザー型とは、ホストOSを使わず直接サーバーにインストールし仮想マシンを動かすことです。ハードウェアのリソースを直接管理できます。

##ホストOSとゲストOS
仮想化・仮想マシンに関連してよく出る用語が「ホストOS」と「ゲストOS」です。
ホストOSは仮想環境の土台となるOSのことで、ゲストOSは仮想マシン上にインストールされたOSのことです。
たとえば、Linuxサーバ上に仮想マシンを作り出しWindowsをインストールしたら、ホストOSはLinuxでゲストOSはWindowsということになります。

#仮想マシンとDockerコンテナの違い
仮想マシンはマシン単位での仮想化であるのに対して、Dockerコンテナはプロセス単位での仮想化となっています。
仮想マシンは自由度が高い一方で、リソースの消費が激しいです。
それに対して、Dockerコンテナは仮想マシンよりも軽量ですが、OSをホストと共有するため自由度は下がります。
【Unity】オブジェクトをなめらかに動かす

#やりたいこと
　HPゲージのゲージやオブジェクトの移動を等速にではなく、「はじめは速く、最後はゆっくり」
　として『動き』を付けたい。

# Lerp
<blockquote class="twitter-tweet" data-lang="en"><p lang="in" dir="ltr">Lerp <a href="https://t.co/GoFLSMtYyB">pic.twitter.com/GoFLSMtYyB</a></p>&mdash; めぞふち (@mezofuchi) <a href="https://twitter.com/mezofuchi/status/1185407374871289856?ref_src=twsrc%5Etfw">October 19, 2019</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

1次ベジェ曲線
・UnityのLeapを使用
・等速であるためなめらかな動きにはならない。

# Slerp
執筆中





# 参考サイト
[【Unity】曲がる弾をつくる（2D）](https://aoaoaoaoaoaoaoi.hatenablog.com/entry/2018/10/28/225531)
[【Unity】ベジェ曲線を学び、実装する](https://setchi.hatenablog.com/entry/2017/04/08/191455)
Rails チュートリアル　第４章　まとめ

問題提起
トップページには Home | Ruby ---ではなくて、 Ruby ----がベター
→トップページのみ | なしで基本タイトルのみ表示、それ以外はHome | Rのように表示したい
解決策
Helperメソッドで対処、generateで生成されるもので、便利そうなものを置いておく場所

Helperメソッドの実装、このときRubyの文法がわからないとコードが書けない


```ruby:app/helpers/application_helper.rb
module ApplicationHelper

  # ページごとの完全なタイトルを返します。
  def full_title(page_title = '')
#もし何か渡されたらpage_titleに入れる、何も渡されなかったら空文字を入れる
    base_title = "Ruby on Rails Tutorial Sample App"
    if page_title.empty?
      base_title
    else
      "#{page_title} | #{base_title}"
    end
  end
end

```
これをapplication.html.erbで、<%= full_title(yield(:title)) %> のように使う
もし、full_titleに追加タイトルありが入ってくれば、full_title(Help)となるので、if-else文はpage_title=Helpからemptyではないので、elseに行き、Help | Ruby on--- が表示される

もし、full_titleに""が入ってくれば、trueなのでRuby on ---だけが表示される
オプション引数で""を指定しているので、home.htmlからprovideを消してもいい
full_title(yield(:title)が実行された場合、yield(:title)がなければオプション引数の""が実行されるから（ここの論理の流れは要復習）

Ruby----
Rubyの世界では、あらゆるものがオブジェクト
オブジェクトにメッセージを投げたら、そのオブジェクトが受け答えしてくれる
例えば

```rb:
"foobar".length
=> 6
```
foobarという文字列オブジェクトに長さは何かというメッセージ(length)を投げたら、6というメッセージを返してくれる
1.to_s "foobar".reverseも同様

nil、true、falseもオブジェクト、オブジェクトであればメッセージの受け渡しができるから
こうしたあらゆるものがオブジェクトである言語を、オブジェクト指向という

Rubyの思想、and or unless 人間のやりたいことをコンピュータが推測してくれ
自由　インデントで強制をかけない

irbとRails consoleは少し違う（.secondなど、railsであったらいいと思う機能も用意されている）

eachは万能だが、配列を作りたいならmapのように細かいブロック付きメソッドは用意されている

ハッシュ　{}
キーと値、タンスのラベルと中身でイメージする

```
user["name"] = "---"
```

実際は、ラベルとして文字列オブジェクト"name"を使わず、シンボルオブジェクト:nameを使う

```
user[:name] = "---"
```

シンボルを使う理由は、文字列はオブジェクトが毎回変わるのでコンピュータにその場所を毎回調べてもらう必要があってコストがかかる。シンボルは数字と同様に、オブジェクトの場所が変わらないので、コンピュータにとって負担が少なく、それでいて数字よりも中身を人間が理解しやすいので、ラベルで使われる
オブジェクトの場所はuser[:name].object_idで調べることができる

組み込みクラスの変更を許容、よくわからない
OpenStreetMap coastline（海岸線）＋ water （陸水域）から GeoJSON Polygon 生成

こんにちは。
OpenStreetMap natural=coastline （海岸線） と natural=water （陸水域） のデータから、海＋陸水の GeoJSON Polygon を作りました[^1]。

「[OpenStreetMap coastline（海岸線）から GeoJSON LineString 生成](https://qiita.com/kkdd/items/4b8b940f7b4e457e6a32)」の続編です。同じく [OSMCoastline](https://osmcode.org/osmcoastline/)（および homebrew）を利用しています。日本の例です[^2]。
<img width="556" alt="water.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54617/b3f7380f-edfb-c428-b141-105d39552a7b.jpeg">

[^1]: "[OSM Water Layer: Surface Waters in OpenStreetMap](http://hydro.iis.u-tokyo.ac.jp/~yamadai/OSM_water)" (Dai YAMAZAKI's website) も参考になります。 ↩
[^2]: これの結果を見ますと OSM データの natural=water のタグ付けはあまり完全ではないようです。

```console
$ brew install jq gdal osmcoastline
$ 
$ wget http://download.geofabrik.de/asia/japan-latest.osm.pbf
$ osmcoastline -p water -o japan-coastline.db japan-latest.osm.pbf
$ ogr2ogr -f "GeoJSON" japan-coastline.json japan-coastline.db water_polygons
$ 
$ ogr2ogr -f "GeoJSON" japan-water.db japan-latest.osm.pbf -sql "SELECT OGR_GEOM_WKT from multipolygons WHERE natural='water'" -dialect OGRSQL
$ jq '.features[]' japan-coastline.json japan-water.db | jq -s '{"type":"FeatureCollection", "features":.}' | gzip > japan-coastline_water.json.gz
```
コンソールログのcommit transactionはエラーではなく、DBへの変更記録

## はじめに
Rails以外でも役立つ知識です。

今回はRailsコンソールに出てくる**「commit transaction」**というログを例にコンソールログの内容や用語の解説などをまとめました。
<br>

## コンソールで出てくる以下の**「commit transaction」**というログはエラーではない
```console
$ rails console
irb(main):005:0> Product.create(name: "Product1", description: "fisrt product")
   (0.1ms)  begin transaction
  Product Create (2.3ms)  INSERT INTO "products" ("name", "description", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["name", "Product1"], ["description", "fisrt product"], ["created_at", "2019-08-29 10:41:04.396182"], ["updated_at", "2019-08-29 10:41:04.396182"]]
   (2.1ms)  commit transaction
=> #<Product id: 1, name: "Product1", description: "fisrt product", created_at: "2019-08-29 10:41:04", updated_at: "2019-08-29 10:41:04">
```

見出し通り、**「commit transaction」**はエラーではなく、**「正常にデータベースに変更を加え終えた」**というメッセージです。

データベースに変更をくわえる手続きを**「トランザクション」**と言います。
ログは`begin transaction`の部分からデータの挿入を行い、それが**「正常に完了した」**ことを示す`commit transaction`で締めくくられています。
<br>

## コミットとロールバックについて
トランザクションを行うとき、データベースに矛盾を起こすようなデータを挿入しないようにしなくてはなりません。
例えば、**「ユーザー名を未入力の人を登録できないようにする」**といったような制約を設ける必要があります。

その制約に引っかかり、矛盾したデータが挿入されそうになると、トランザクションは中断されデータベースは完全に前の状態に戻ります。
この巻き戻しを**「ロールバック」**と言います。

制約に引っかからず正常にデータの更新が行え、変更が反映されることを**「コミット」**と言います。
もし、以下のようなModelのバリデーションをつけていたとします。

```console
app/models/product.rb

class Product < ApplicationRecord
  validates :name, presence: true
end
```

Productのnameは空ではいけないというバリデーションなので、以下のようにnameが空の誤ったデータを挿入しようとしても、ロールバックされるわけですね。

```console
$ rails console
irb(main):007:0> Product.create(description:"second product")
   (0.4ms)  begin transaction
   (0.1ms)  rollback transaction
=> #<Product id: nil, name: nil, description: "second product", created_at: nil, updated_at: nil>
```

ちなみに直接createするのではなく、newしてからセーブする方法だと、newした段階で正常かどうか判断できます。

```console
$ rails console
irb(main):001:0> p = Product.new(description: "third product")
=> #<Product id: nil, name: nil, description: "third product", created_at: nil, updated_at: nil>
irb(main):002:0> p.valid?
=> false
irb(main):003:0> p.errors.messages
=> {:name=>["can't be blank"]}
irb(main):004:0> p.save
   (0.4ms)  begin transaction
   (0.1ms)  rollback transaction
=> false
```

ログが大量に出てきたからといって、間違った動作をしているという訳でもないときもあります。
ログはフレームワークや言語の設計者からの親切なメッセージですので、必ず目を通してあげてください。
<br>

## 参考
この記事は「CodeShip」内での実際の質疑応答や指導・アドバイスの一部を基に作成しています。
cmderでgithubを利用している際のPermission denied (publickey)対策

Windowsのコマンドプロンプトをかっこよく使うためのコンソールソフト[cmder](https://cmder.net)でgitを使っていると、ふとした拍子に次のエラーが表示されてgithubに接続できなくなることがあります。

```sh
$ git pull
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

# 解決策

次の箇所で指定可能なsshの設定を見直すと良いです。

1. C:\Program Files\Git\etc\ssh\ssh_config
1. C:\Program Files (x86)\Git\etc\ssh\ssh_config
1. C:\\\<cmderのインストール先>\cmder\vendor\git-for-windows\etc\ssh\ssh_config
1. C:\Users\\\<ユーザ名>\\.ssh\config

# 解説

cmderに限らずWindowsでgitを利用する際は(WSLは別として)何らかのgitクライアントをインストールしますが、接続先の鍵情報などはsshの設定ファイルに記述します。

1や2のファイルはgit for windows用のssh設定として多くのサイトで紹介されていますが、cmderはFULLを指定してインストールすると独自のgit for windowsを別途インストールするので設定ファイルの場所が変わり、3のファイルとなります。ここまでは結構検索に引っ掛かるのですが、最近オリジナルのgit for windowsを再インストールした際に冒頭のエラーが出るようになり、調べると4のファイルへ設定が必要になっていました。

# 設定内容(参考まで)

参考までに、ssh_configや.ssh/configへ追記するgithubへの最低限の接続設定は次の通りです。

```sh
Host github.com
    HostName github.com
    User git
    IdentityFile C:/<鍵ファイルの格納フォルダ>/<github用の秘密鍵>
```
古いApacheで中間CA証明書が認識されていなかった

# TL; DR

* Apache 2.4.8 以降と以前で中間CA証明書の設置方法が違う
* 古いApacheの場合、中間CA証明書は `SSLCertificateChainFile` で指定しないとダメ
    * (2.4.8以降と同様に) `SSLCertificateFile` に連結していても読み込まれない

# はじめに

中間CA証明書の設定は、例えうまく設定されていなくてもブラウザによってはきちんと表示されるので見落としがちな問題である。
しかし、スマートフォンからの通信や、Facebook などのサイトでシェアする場合の OGP タグ情報の読み込みなどを行う場合、中間CA証明書が正常にインストールされていないとうまく通信ができない。

そこで何が起きてるのかを調べると初めて知ったことがあったので記載。

# 中間CA証明書ファイルの配置方法

Apache・nginx ともに以下のコマンドで中間CA証明書を含んだ１ファイルを参照する記載が多かったです。 

```bash
# ミドルウェアから ssl.crt を証明書として参照する
$ cat [ssl証明書] [CA中間証明書] > ssl.crt
$ cat ssl.crt
-----BEGIN CERTIFICATE-----
(SSL証明書)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(中間CA証明書)
-----END CERTIFICATE-----
```

しかし、Apache 2.4.8 以前では中間CA証明書を指定するディレクティブとして `SSLCertificateChainFile` が存在し、これで中間CA証明書ファイルを指定してあげる必要がありました。 2014年ぐらいの変更ですので、SSL証明局のページでも説明が併記してあることもあります。

最初、既存の設定ファイルを見たときには「古い中間CA証明書ファイルの指定方法は消えたけれど、`SSLCertificateFile` で指定しているファイル内に中間CA証明書は書かれているので、中間CA証明書は有効になっているだろう」と考えていたのですが、これが大間違いでした。 
古いバージョン ( `SSLCertificateChainFile` ディレクティブが有効なバージョン) のApacheでは **このディレクティブで指定しない限り中間CA証明書は有効になりません** 。 なお、中間CA証明書を併記した crt ファイルは中間CA証明書を含まないSSL証明書として正常に認識されます。


# まとめ

古い Apache が動いているサーバーに対する `curl -I https://...` が失敗する場合は、このあたりの設定が古い Apache ベースのものになっているかを確認するようにしましょう。

私がSSL周りをやり始めたのが 2014年以降なので、このあたりの勘違いを起こしたというのはあります。 

|ミドルウェア  |バージョン   | SSL証明書指定  | 中間CA証明書指定 |
|-------------|------------|---|---|
|Apache       | 2.4.8 以降  | `SSLCertificateFile $(cat [SSL証明書] [中間CA証明書])`  | 不要 (SSL証明書指定に含まれる) |
|Apache  | 2.4.8 以前  | `SSLCertificateFile [SSL証明書]` | `SSLCertificateChainFile [中間CA証明書]` |
|nginx   | (指定なし)  | `ssl_certificate $(cat [SSL証明書] [中間CA証明書])`  | 不要 (SSL証明書指定に含まれる) |
Windows10でいつの間にか英語入力モードになってしまう現象を止める

# はじめに
`Shift + 左Alt` で日本語⇔英語が切り替わるか確認して下さい。
　→切り替わった方は本記事で解決します。
　→切り替わらなかった方は申し訳ございません、お引取り下さい。

# 手順
![設定 2019-10-19 12.35.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201656/e203b550-acef-890d-446a-d9959a6e4fec.png)

![設定 2019-10-19 12.36.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201656/05a1b308-e943-349b-b494-bedb9d81fb20.png)

![設定 2019-10-19 12.37.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201656/2d0f1ab0-02f2-e9e8-7a96-03536d2b9145.png)

![テキスト サービスと入力言語 2019-10-19 12.38.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201656/811d54c0-ba60-882d-f8b4-0c254ccb5b8b.png)

![キー シーケンスの変更 2019-10-19 12.43.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201656/7913e297-e128-e7fb-cb3e-7a8cabd205f4.png)
pandas.DataFrameとMySQLの連携

pandas DataFrameのデータをMySQLへ保存したり、逆にMySQLのテーブルをDataFrameとして読み込む方法についてメモ。
magicコマンドを使うので、Jupyter上での操作を想定です。

## 1.使うライブラリ
私は下記のライブラリを使っています。ライブラリの役割は下記のとおり。

|ライブラリ|役割|
|:-----------|:---------------------------------|
|PyMySQL|MySQLと接続するコネクタ|
|sqlalchemcy |python製の[ORM](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E9%96%A2%E4%BF%82%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0)|
|ipython-sql|jupyter上でsqlを実行できるようになる|

インストールしてなければ、インストール。

```{bash}
$ pip install PyMySQL
$ pip install sqlalchemy
$ pip install ipython-sql
```

## 2.接続するデータベースの設定
接続するためのエンジンを作成。

```{python}
import pandas as pd
import sqlalchemy as sa

url = 'mysql+pymysql://username:password@hostname:port/dbname?charset=utf8'
engine = sa.create_engine(url, echo=False)
```


## 3.データの受け渡し
pandasのDataFrameをMySQLに保存する。DataFrameはpandasの関数が使えるのでデータベースとの連携が簡単！
ただ、```if_exsits = 'replace'```にしておくと、テーブルが問答無用で上書きされるので、本番環境では非推奨。
また、通常の設定のままだと1行ずつインサートするため、非常に時間がかかる。
引数```method = "multi"```を設定すると複数行をまとめてインサートでき、引数```chunksize```を設定すると、インサート時の行数の上限が設定できる。

```{python}
df.to_sql('df', engine, index=False,  
           method = "multi",chunksize = 10000 ,if_exists='replace')
```

## 4.データの読み込み
データベースにあるテーブルをpandas.DataFrame形式で読み込む。pandasのread_sql関数が簡単。

```{python}
query = "select * from dbname.df"
df = pd.read_sql(query,con = engine)
```

## 5.Jupyter上でのSQL操作
magicコマンドを読み込んでやると、```%%sql $url```でsqlに接続できるようになり、セルからqueryをなげられる。

```{python}
%load_ext sql
```
```{python}
%%sql $url
SHOW TABLES;
```

## 6.JupyterLab extension
セルからちょろっと操作するのでなく、もっとがっつりqueryを書いたり、データをしっかり見にいく必要がある場合には、JupyterLab extensionのjupyterlab-sqlがフィットするかも。
https://github.com/pbugnion/jupyterlab-sql
Google Colaboratory の猫、コーギーモード

Google Coaboratory は環境構築することなく簡単にJupyterノートブック、GPUが無料で使用できる神のようなサービスです。
設定を見ていると不思議な設定が、、

コーギーモード、猫モード？
チェックを入れると画面内でコーギーと猫が歩いてくれます
そ・れ・だ・け！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258389/4a534e23-1457-2b0e-a5f7-ed98c6098f0a.png)
Nimの関数は当然第一級オブジェクト

# はじめに
Nimの関数は当たり前のように第一級オブジェクト。
[第一級オブジェクト - Wikipedia](https://ja.wikipedia.org/wiki/%E7%AC%AC%E4%B8%80%E7%B4%9A%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88)

# 変数に入れてみる
```nim
proc hello(n: int): string =                                                    
  "numbar is " & $n  
  
let f = hello
f(42).echo      
```
# コレクションに入れてみる
```nim
import sugar                                                                    
var commands: seq[proc(): string]                                               
commands.add(() => "hello")                                                     
commands.add(() => "world")                                                     
for c in commands:                                                              
  c().echo                                                                      
                                                                                
# こうも書ける        
for c in [() => "hello", () => "world"]:                                        
  c().echo    
```
# 関数を引数にとる関数を定義
```nim
proc execute(f: proc(): string) =                                               
  f().echo
                                                                                
proc helloWorld(): string =
  "hello world"                                                 
  
execute(helloWorld)                                                             
# nimだからこうも書ける                                                         
helloWorld.execute
```
以上〜。
デバッグの進め方について個人的に意識したいことをまとめてみた

## はじめに

仕事をしているなかで、不具合のデバッグを担うことは多々あると思います。最近個人的に難しいデバッグを担当し、社内の先輩と相談しながら進めたのですが、その時どうやってデバッグを進めるのかをふりかえって話しました。その内容を備忘も兼ねてまとめようと思います。

## tl;dr

この記事のサマリです。

* 闇雲に調べても解決には近づかない
* ゴールから逆算する進め方は解決に近づきづらい
* マイルストンを細かく置き、仮説・検証・理解を繰り返しながら進める
* 理解を得るための情報を網羅的に、正確に収集する

## 闇雲に調べても解決には近づかない

デバッグを始めるときの状況は様々です。ユーザーからの不具合報告ですぐに修正する必要があったり、修正までの期限が設定されていたりすることもあります。

その上で、自分の開発していない外部ライブラリに問題が発生しているような難易度の高い問題だと、いつ解決するかすぐに見積もることができずに焦ることもあると思います。

そんな状況だと、早く解決してしまいたいという気持ちがはやってしまい、闇雲に原因を調べてしまうという行動に陥りがちです。自分の経験上、この状態に陥ったときに、デバッグがうまく行ったことはほとんどありません。

闇雲に調べている状態は、次にどんな情報を集める必要があるか、どこを調べる必要があるかといった、次のアクションがわからない状態とも言い換えられると思います。

[新装版 達人プログラマー 職人から名匠への道](https://www.amazon.co.jp/dp/B06W567M44) にも、デバッグは「**単なる問題解決**」であり、「**パニックに陥らないこと**」が大切だと書いてあります。闇雲になっているなと自分自身で気づいたら、進め方を再考してみると良いかもしれません。

## ゴールから逆算する進め方は解決に近づきづらい

また、早く原因を特定して解決したいという気持ちがあると、真っ先にソースコード修正箇所を読んで探すということが起きがちです。

一見解決に近そうですが、原因がはっきりしないままソースコードを読みに行くことは、簡単なデバッグであれば解決することもあるかもしれませんが、根の深い難しいデバッグの場合は解決することは難しいと思います。

開発タスクではゴールから逆算してタスクを分解していくことができますが、デバッグの場合は原因というゴールが不明確であるため、ゴールから逆算するということが難しいのかなと考えています。

## マイルストンを細かく置き、仮説・検証・理解を繰り返しながら進める

それではどうデバッグを進めればいいかを社内の先輩と話したのですが、まとめると以下のような進め方になるのではという話になりました。

* 現時点ではわからないが、調べればすぐにわかりそうな仮説をマイルストンとして置く
* マイルストンとしておいた仮説について検証し、わかった情報を集めて整理・考察・理解する
* 次の仮説をマイルストンとして置く、再度検証・考察・理解する

ゴールからではなく、現時点というスタートからマイルストンを細かく置き、徐々に情報や理解を積み重ねていく進め方となります。一見面倒で時間がかかりそうではありますが、確実に解決には近づく進め方だと思います。

マイルストンを細かく置くことで、これから何を調べようとしているかがより明確になります。また、現時点で自分が得た情報や気づいたことについても理解が伴った状態で進めることができます。アジャイル開発の進め方とも似ていると思います。

## 理解を得るための情報を網羅的に、正確に収集する

よくデバッグでは、再現条件を明確にすることがまず大切だと言われます。そのために様々なユーザー操作やパラメータを変更したテストによって、情報を収集し、理解をしていくことが必要になってきます。細かくマイルストンを置いた形で進めたとしても、各マイルストンで得た情報で理解を進めることが出来なければ、次のアクションに移ることが出来ません。

そこで必要になることとしては、理解を得るための情報を網羅的に、正確に集めるということです。ここでも闇雲にユーザー操作やパラメータを操作するのではなく、例えばスプレッドシートで網羅的にユーザー操作パターンをテストしたり、パラメータを場合分けして変更しつつ調べたりすることで、理解を得るための新たな情報や気づいたことを得られる可能性が高くなります。

情報を得るための手段は様々です。ブラウザの開発者コンソールやデバッガはもちろんですが、単純に画面を操作するだけでも理解を得るための情報が得られることがあります。その時々のマイルストンにおいて、適切な手段が何かを考えてみると良さそうです。

## おわりに

この話をするなかで、デバッグは化学実験や大学の研究、競技プログラミングの問題を解くことなどに似ていると思いました。現状から理解をしつつ解決に近づくことが大切だと思います。

自分のデバッグ力はまだまだですが、この記事でまとめたことを活かしてデバッグに取り組みたいと思います。

## 参考文献

* [新装版 達人プログラマー 職人から名匠への道](https://www.amazon.co.jp/dp/B06W567M44)
Google Cloud StorageとAWS S3との間でファイルをコピーするには


なんと`gsutil`コマンドはS3を直接サポートしている！

# gsutil cpコマンド

`gsutil cp`でGoogle Cloud StorageからS3へのコピーができます。

```
$ gsutil cp gs://xxxx/foo.tar.gz s3://yyyy/foo.tar.gz
Copying gs://xxxx/foo.tar.gz [Content-Type=application/x-tar]...
- [1 files][  4.3 MiB/  4.3 MiB]
Operation completed over 1 objects/4.3 MiB.
```

ただし、大きなファイルは対応していないようです。

```
$ gsutil cp gs://xxxx/foo.tar.gz s3://yyyy/foo.tar.gz
CommandException: "gs://xxxx/foo.tar.gz" exceeds the maximum gsutil-supported size for an S3 upload. S3 objects greater than 5 GiB in size require multipart uploads, which gsutil does not support.
```

5GiBを超えるファイルはコピーできないとのこと。

逆向きのS3からGoogle Cloud Storageへのコピーもできます。

```
$ gsutil cp gs://xxxx/foo.tar.gz s3://yyyy/foo.tar.gz
```

念のため、さすがに`aws`コマンドはGoogleへの対応はしてないよなって思いながら試してみたら、

なんと`aws`コマンドもGoogle Cloud Storageを直接サポートしている！

# aws s3 cpコマンド

`aws s3 cp`でコピーできます。

```
$ aws s3 cp s3://yyyy/foo.tar.gz gs://xxxx/foo.tar.gz
download: s3://yyyy/foo.tar.gz to gs:/xxxx/foo.tar.gz
```

`/`が1つ足りない気がするが。。。

逆向きもコピーできます。

```
$ aws s3 cp gs://xxxx/foo.tar.gz s3://yyyy/foo.tar.gz
upload: gs:/xxxx/foo.tar.gz to s3://yyyy/foo.tar.gz
```

やっぱり`/`が1つ足りない。。。

aws cliでの巨大ファイルのgsからs3へのコピーはなぜか以下のようなエラーになりました。なんでだろう。

```
$ aws s3 cp gs://xxxx/foo.tar.gz s3://yyyy/foo.tar.gz
The user-provided path gs://xxxx/foo.tar.gz does not exist
```

# gsutil lsコマンド

なんと`gsutil ls`もS3を直接サポートしている！

```
$ gsutil ls -l s3://yyyy/
...
```

しかし`aws s3 ls`はGoogle Cloud Storageには対応していませんでした。

```
$ aws s3 ls gs://xxxx/
Parameter validation failed:
Invalid bucket name "gs:": Bucket name must match the regex "^[a-zA-Z0-9.\-_]{1,255}$"
```

# 大きなファイルのコピー

パイプで2つのコマンドをつなげばよいです。以下のようにします。`gsutil cp`、`aws s3 cp`ともにパラメータに`-`を渡すと標準入力または標準出力になります。

```
$ gsutil cp gs://xxxx/foo.tar.gz - | aws s3 cp - s3://yyyy/foo.tar.gz
```

これだと進捗表示がなくて不安になるのですが、その場合は`pv`コマンドを挟みます。

```
$ gsutil cp gs://xxxx/foo.tar.gz - | pv | aws s3 cp - s3://yyyy/foo.tar.gz
457MiB 0:00:33 [13.6MiB/s] [        <=>                                         ]
```

参考
[pvコマンド(Linuxのパイプの流れの進捗を見守るには)](https://qiita.com/suzuki-navi/items/a851d9ec66d2cf4bf732)

# まとめ

整理すると、以下のとおり。

`cp`

| | gs -> s3 | s3 -> gs |
|:--:|:--:|:--:|
| `gsutil cp` | 可 | 可 |
| `aws s3 cp` | 可 | 可 |

大きなファイルの直接の`cp` (パイプでつながない方法)

| | gs -> s3 | s3 -> gs |
|:--:|:--:|:--:|
| `gsutil cp` | 不可 | 可 |
| `aws s3 cp` | 不可 | 可 |

`ls`

| | gs | s3  |
|:--:|:--:|:--:|
| `gsutil ls` | 可 | 可 |
| `aws s3 ls` | **不可** | 可 |

# バージョン情報

```
$ aws --version
aws-cli/1.16.222 Python/3.7.4 Linux/4.15.0-65-generic botocore/1.12.212
$ gsutil --version
gsutil version: 4.38
```

# 参考

[gsutil、aws s3での基本的なファイル操作（Google Cloud Storage、S3） - Qiita](https://qiita.com/suzuki-navi/items/775b9f9029af19780be3)
android studioで削除したパーミッションが生き残ってる時の対応

#経緯
android manifestでいらないパーミッションを消したい
＞間違いなく消してるのにどっかから検出されてる
＞別ライブラリで使ってるオチ

普通に全部検索して消せばOKなのですが、それをやってられない時用の対応メモ

#参考サイト
http://blog.riskfinder.co.jp/2015/10/android-studio.html
https://mrtry.hatenablog.jp/entry/2017/12/07/000000
https://developer.android.com/studio/build/manifest-merge.html
一番最後のは公式

#対応方針
上記参考サイトによると、ライブラリとか使ってて複数manifestがあるときはビルドの時に統合されるらしい。
今回いじるアプリは大量のライブラリを使ってるので確かにこの中にあってもおかしくない…
この統合ツールは結構いろんなことができるらしいので、今回はそれを使って「特定のパーミッションは統合しない」という対応

ひとまず現状確認
ちなみに今回消したいのはC2D_MESSAGEです。GCM用のものなので不要
`./build/intermediates/manifests/full/debug/AndroidManifest.xml`
が統合結果とのこと。確かに

```
<permission
    android:name="{パッケージ名}.permission.C2D_MESSAGE"
    android:protectionLevel="signature"/>
```
の記述がある。これを見て削除できたかどうかのチェックをする。逐一クリーンビルドして確認

#対応

＞applicatonタグに`xmlns:tools="http://schemas.android.com/tools"`を追加したのち、

```
<{消したいパーミッションと全く同じ記述} tools:node="remove"/>
```
をmanifestに追加で消えるはず

#引っかかったところメモ
パッケージ名はもちろん、タグ名や他のプロパティまで全く同じ記述にしないと消えないようです。
下記は実際の事例

```
<uses-permission android:name="{パッケージ名}.permission.C2D_MESSAGE" tools:node="remove"/>
```
を追加
＞消えない
＞他のプロパティを記述してなかったので、

```
<uses-permission
    android:name="{パッケージ名}.permission.C2D_MESSAGE"
    android:protectionLevel="signature"
    tools:node="remove"/>
```
に変更
＞消えない
＞統合結果をよーーーく見ると、

```
<permission
    android:name="{パッケージ名}.permission.C2D_MESSAGE"
    android:protectionLevel="signature"/>
```
だった…（uses-permissionじゃない。）

```
<permission
    android:name="{パッケージ名}.permission.C2D_MESSAGE"
    android:protectionLevel="signature"
    tools:node="remove"/>
```
に変更
＞消えた！が、

```
<uses-permission android:name="{パッケージ名}.permission.C2D_MESSAGE"/>
```
が生き残ってた…

```
<uses-permission android:name="{パッケージ名}.permission.C2D_MESSAGE" tools:node="remove"/>
```
を追加
＞これで全部消えた！！

#所感
記述は簡単（今回は消したいパーミッションの末尾に`tools:node="remove"`をつけるだけ）
結構いろんなことやってくれて便利そう。
ただ記述は正確にしないとはまる。
dockerでさくっとC言語の hello world

大学ぶりにC言語をやってみたいな〜と思い、dockerでサックとgccの環境を構築してみました。

gccのイメージが入ったコンテナを起動します。イメージを持っていない場合はdockerが自動でimageをプルしてくれます。

```bash
docker run -v "$PWD":/usr/src/myapp -w /usr/src/myapp -it gcc:4.9

# -v ローカルのvolumeをコンテナにマウント
# -w コンテナのworkdirを定義
# -it コンテナにログイン
```

早速c言語でハローワールド

```app.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    printf("Hello World!\n");
    printf("ハローワールド!\n");

    return 0;
}
```

app.cをコンパイルし、実行ファイルを実行

```bash
$ gcc app.c -o a.out 
$ ./a.out

# 出力結果
# Hello World!
# ハローワールド!
```

## 番外編

stdlib.h + argv を使ったサンプル

```app.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int i, result = 0;
    
    for (i = 1; i < argc; ++i)
    {
        printf("argv[%d] = %s\n", i, argv[i]);

        result += atoi(argv[i]);
    }

    printf("Total Sum = %d\n", result);

    return 0;
}
```

実行結果

```bash
$ gcc app.c -o a.out 
$ ./a.out 1 2 3

# 出力結果
# argv[1] = 1
# argv[2] = 2
# argv[3] = 3
# Total Sum = 6
```
Nimで変数の型名を確認する

# はじめに
Nimは型推論してくれるので、型を意識しなくても割と使えるど
いざ関数定義とかで型を書く必要が出てきたときに困ったりしてた。

# で、どうやんの？
typeでOK。

```nim:
type X = object of RootObj                                                      
type RefX = ref object of RootObj                                               
proc someFunc(n: int): string = $(n * 2)
echo (new X).type                                                               
echo X().type                                                                   
echo (new RefX).type                                                            
echo RefX().type                                                                
echo 3.type                                                                     
echo 3'i8.type                                                                  
echo 3'u.type                                                                   
echo 3'u32.type                                                                 
echo "hello".type                                                               
echo 'a'.type                                                                   
echo (42, 'c', "string").type                                                   
echo someFunc.type
```

```text:実行結果
ref X
X
RefX
RefX
int
int8
uint
uint32
string
char
(int, char, string)
proc (n: int): string{.noSideEffect, gcsafe, locks: 0.}
```

以上〜。
#Rails の ActionMailer で 共通のヘッダ・フッタをテンプレートとして利用する

- 各mailerのテンプレート内でrender で読み込む
- もっと良い方法があるかもね？

# views/some_maler/hello.text.erb

```
<%= render "/mailer/header" %>

こんにちはー！

<%= render "/mailer/footer" %>
```

# app/views/mailer/_header.text.erb

```
親愛なるXX様

```

# app/views/mailer/_footer.text.erb

```
------------------------------------------------------------------
[お問い合わせ先 ]

mail：xxxx@xxx.xx.xx
https://example.com
```

# NOTE

- どうでもいいけど render の path 指定ってほんと訳わからないよね。パスが間違っているときは、エラーメッセージに、読み込もうとしているパスが書かれてたりするから読んでみて！

`views/mailer/_footer` <- こういうやつ！

```
     Failure/Error: <%= render "/views/mailer/footer" %>

     ActionView::Template::Error:
       Missing partial views/mailer/_footer with {:locale=>[:ja], :formats=>[:text], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder]}. Searched in:
         * "/app/app/views"
         * "/usr/local/bundle/gems/kaminari-core-1.1.1/app/views"
```



# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
[IE、Edge対応]imgをbackgroud-sizeのようにトリミング、拡大縮小できるobject-fitにできないこと

できないこととタイトルには書きましたが、正確には少し調整すればできます。

img要素をbackgroud-sizeのように表示させられるobject-fitについて。
IEやEdgeでは対応していないため、[object-fit-images](https://github.com/fregante/object-fit-images) というJSで補ってあげる必要があります。

object-fitの詳しい実装方法はWebクリエイターボックスの以下の記事を参考にしてください。
[1行追加でOK！CSSだけで画像をトリミングできる「object-fit」プロパティー
](https://www.webcreatorbox.com/tech/object-fit)

## IE、Edgeでできないこと
**画像をJSなどでDOM生成する場合などは実装することができません。**
例えばモーダルのギャラリーなどがありますが、
img要素をフロント側で生成する場合はIEやEdgeでは動作しません。

## object-fit-imagesはbackgroud-sizeで代替している
object-fit-imagesはIE、Edgeではbackgroud-sizeで代替する仕組みで、
DOMが読み込まれた後にobject-fit-imagesの関数が実行され、
srcを取得してbackgroud-imageに置き換えている。

そのためJSなどでimgを生成もしくはsrcを変更している仕組みではobject-fit-imagesは使えません。
もしobject-fitのような動きにしたいなら最初からbackgroud-sizeで指定するのも良いかもしれません。

```html:html
<div class="imgWrap" style="backgroud-image: url('[JSで生成]');">
  <img class="img" src="ダミー" alt=""> ← 高さや幅を保持する用
</div>
```

```css:css
.imgWrap {
  background-size: contain;
  background-position: 50% 0; ←拡大縮小の基準値
  background-repeat: no-repeat;
}
```

画像を生成した際にobject-fit-imagesの関数を都度読込すれば良いのかもと思ったので、やってみてできるかできないかは、また追記します。


## 追記（2019.10.19）
生成した後にobject-fit-imagesの関数を実行すれば問題なく動作しました。
（細かい記述は省いてます）
こちらのほうが記述としては簡単。

```javascript:javascript
const _createElement = () => {
  〜画像生成の記述は省略〜
  //画像生成した後に↓ クラス名は生成したと分かる名前に
  objectFitImages('img.create-object-fit-img');
};
```


## まとめ
- object-fit-imagesはIE、Edge用のポリフィル
- object-fit-imagesはbackgroud-sizeで代替している
- imgをフロント側で生成、変更している場合はimg要素生成後にobjectFitImages()を都度実行する
- object-fitを使わない場合はbackgroud-sizeで対応する（レスポンシブがめんどくさい）

以上。
CSSでTable Cellに余白を作る方法

#はじめに
bootstrapで実装していたTable Cellに余白を作る際に少しハマったのでメモです。
#HTMLとCSS
[bootstrap Examplesより](https://getbootstrap.jp/docs/4.2/content/tables/)
##HTML
```html
<table class="table table-borderless">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">First</th>
      <th scope="col">Last</th>
      <th scope="col">Handle</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td>Mark</td>
      <td>Otto</td>
      <td>@mdo</td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td>Jacob</td>
      <td>Thornton</td>
      <td>@fat</td>
    </tr>
    <tr>
      <th scope="row">3</th>
      <td colspan="2">Larry the Bird</td>
      <td>@twitter</td>
    </tr>
  </tbody>
</table>
```
##CSS
```css
th,
td {
	border-right: 1px solid #104A9E !important;
    color: #104A9E;
}
```
<img width="569" alt="スクリーンショット 2019-09-14 16.39.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268079/4a403c03-6133-de2f-71e9-d09c2b5d0dba.png">
#変更点（CSS)
CSSで背景色と同じborderを追加して余白があるように見えるように変更。

```css
th,
td {
	border-right: 1px solid #104A9E !important;
    color: #104A9E;
}
/* 追加 */
tr {
    border-bottom: 10px solid #e9f1f9;
}
```
<img width="574" alt="スクリーンショット 2019-09-14 16.41.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268079/ef7cee26-e9f5-a2b5-6a28-857cfb4f80a5.png">
D&DしたPDFファイルをSQL Serverに登録＋プレビューする方法

Microsoft&reg; Visual Studio&reg; Community 2019 の Visual C#&reg; と、Microsoft&reg; SQL Server&reg; 2012 の環境で、PDF ファイルをDBに登録＋プレビューしようとして、詰まった所の忘備録です。

Excelファイルの書き換えについても、追記しました。

長いので分けました。

#目次
1. [[C#]ドラッグ＆ドロップの使い方](https://qiita.com/ANNEX_IBS/items/d9ffa76716330c0ce2b0)
2. [[SQL]FILESTREAM/VARBINARY(MAX)の使い方](https://qiita.com/ANNEX_IBS/items/3393a53b6fe27046b3b3)
3. [[C#]PDF ファイル表示方法](https://qiita.com/ANNEX_IBS/items/f7eb7b795915d204a079)
4. [[C#]Excelファイルのセル読取/書込](https://qiita.com/ANNEX_IBS/items/8308fb193dd987c0899e)
unknown attribute '○○○○' for ○○○. →カラムのリネーム

#エラー発生

環境：rails 6

タスクアプリを練習として作っていて、新規登録の実装をして
画面を開いて、動作確認するとこんなエラーが
`unknown attribute 'description' for Task.`
「descriptionがTaskオブジェクトで見つからない~」

#DB確認
DBを見てみよう
ターミナルを開いて

`$rails c`
`$Task.new`
`=> #<Task id: nil, name: nil, descriprion: nil, ~ >`

カラム名が違う!

#カラム名修正
モデル:task
カラム変更前:descriprion
カラム変更後:description

##1.マイグレーションファイル準備
`$ rails generate migration rename_descriprion_column_to_tasks`
（rails generate migration rename_変更前のカラム名_column_to_モデル名複数形）

db/migrate/XXXXXXXXXXX_rename_descriprion_column_to_tasks.rb
というファイルが生成されます

##２.ファイル編集
rename_column テーブル名, 変更前のカラム名, 変更後のカラム名 といった感じで編集します。

```ruby:XXXXXXXXXXX_rename_descriprion_column_to_tasks.rb
class RenameDescriprionColumnToTasks < ActiveRecord::Migration[6.0]
  def change
    rename_column :tasks, :descriprion, :description
  end
end
```

##3.DBに反映

`$ rake db:migrate`
gnuplotの点の透過

`gnuplot 5.0`以上でできる

# データの用意

```
gnuplot> set samp 2000
```
ランダムな点を2000個用意する

# デフォルト

```
gnuplot> p [-0.25:1.25][-0.25:1.25] '+' u (rand(0)):(rand(0))
```

<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221968/e0697cd3-fdf4-ddca-ca62-4893d2d7b416.png>


目を背けたくなるくらい、汚い

# 丸点+サイズ+色

```
gnuplot> p [-0.25:1.25][-0.25:1.25] '+' u (rand(0)):(rand(0)) ps 1.5 pt 7 lc 3
```

<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221968/b9c1d7c1-853a-e353-1e27-743923ae1f4a.png>

`pt`で`pointtype`の指定 (7で太丸)
`ps`で`pointsize`の指定
`lc`で`linecolor`の指定 (color indexで指定。3で水色)

# RGB値で色を指定

```
gnuplot> p [-0.25:1.25][-0.25:1.25] '+' u (rand(0)):(rand(0)) ps 1.5 pt 7 lc rgb 0x0088FF
```

<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221968/ad47a02c-88a0-1cff-f617-1d2b32669ceb.png>

# ARGB値で透過+色指定

```
gnuplot> p [-0.25:1.25][-0.25:1.25] '+' u (rand(0)):(rand(0)) ps 1.5 pt 7 lc rgb 0xAA0088FF
```

<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221968/d854abb5-bbe3-29fc-6760-7c00fa28f228.png>

`tc`(=`texecolor`)はARGBは不可らしい
ちなみに、下記のように`u`(=`using`)の中に色指定を描いてもOK

```
gnuplot> p [-0.25:1.25][-0.25:1.25] '+' u (rand(0)):(rand(0)):(0xAA0088FF) ps 1.5 pt 7 lc rgb variable
```

# pdfでの出力

cairographicのエンジンを使ったpdfcairoで出力すると吉
termの指定は、

```
gnuplot> set terminal pdfcairo color enhanced font "Helvetica,18"
```

です。

なお、postscriptはARGBを扱えないらしい。
LATEXに流すときも、epsではなくてpdfでやったほうが良い模様

参考：
[gnuplot で pdf が出力されない時: 最後にunset outputを指定する](https://gordiustears.net/trouble-of-pdf-terminal-on-gnuplot/)

# おまけ1

```
gnuplot> p [-0.25:1.25][-0.25:1.25] '+' u (rand(0)):(rand(0)):(rand(0)*2):(0xAA0088FF) ps variable pt 7 lc rgb variable
```

<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221968/ffdd39aa-97a4-8608-22e4-2c889787a7d9.png>

`using`の三項目で`ps`に乱数(0~2)を入れている

# おまけ2

```
gnuplot> p [-0.25:1.25][-0.25:1.25] '+' u (rand(0)):(rand(0)):(rand(0)*2):(rand(0)*64):(0xAA0088FF) ps variable pt variable lc rgb variable
```

<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221968/e066dfe2-f34a-6e39-7cf5-bd0687325573.png>

`using`の四項目で`pt`に乱数(0~63)を入れている
(`pointtype`は0~63の64種類がある)



# おまけ3

```
gnuplot> argb(a,r,g,b)=256*256*256*a+256*256*r+256*g+b
gnuplot> p [-0.25:1.25][-0.25:1.25] '+' u (rand(0)):(rand(0)):(rand(0)*2):(rand(0)*64):(argb(rand(0)*256,rand(0)*256,rand(0)*256,rand(0)*256)) ps variable pt variable lc rgb variable notitle
```
<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221968/83137b60-0195-df7b-cc2e-4a0047b33dcd.png>

`argb(a,r,g,b)`という関数で0xAARRGGBB形式を10進数に直して、`using`の第五項で乱数(0~256)を入れている。
`notitle`で、タイトルを消した。

キラキラ〜
ポップアップに対して指定した秒数操作が無かったらBotの実行を止める方法 with VBS

#背景
ユーザーがPCの画面を見ているときだけ実行したい。みたいなケースがあり、作ってみました。
OKとキャンセルのボタンがあるポップアップが出て、指定した秒数の間操作がないと自動的に閉じて、Bot自身の実行も止めてくれる。というものです。

#試した環境
Windows 10
Automation Anywhere Enterprise v11.3.2
Notepad++

#作りかた
Automation Anywhereの標準のPromptコマンドでは希望の動作が実現できないので、VBScriptを使います。
以下のようなコードを書いてAutomation AnywhereフォルダのMy Scriptsに保存。

```vb:PromptForYesNoWithTimeout.vbs
Dim vResult
WScript.Timeout = 30 'タイムアウトするまでの時間（秒）

vResult = MsgBox ("このBotを実行しますか？", 65, "Automation Anywhere Enterprise")
Wscript.Stdout.Writeline(vResult)
```
以下のようなBotを作る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/9fed8467-9068-96f0-dddf-1b68c318ae2d.png)

Run Scriptコマンドの中身はこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/8ac02845-4f69-d2d3-73e7-384d9b7e0da8.png)

ユーザーの操作によって、変数\$Prompt-Assignment$に入る値が変わります。
OKを押したら1
Cancelを押したら2
操作が無くタイムアウトしたら空の値

#動かしてみる
Botをｗ実行すると・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/5afedc10-8e8c-2cf7-33cc-766986070df2.png)


といったポップアップが出て、指定した秒数の間待機したあと、操作が無ければBotの実行が停止されます。
Cancelを押した場合も同様にBotの実行は停止されます。
Catalina をクリーンインストールするもvs codeが開けない問題

Catalinaをクリーンインストールしたので、一から開発環境を整えようとしてvs codeをインストールし開こうとしたらエラーで開けない問題が発生。。。
この時のスクショ撮るの忘れたので実際のエラー画面がないです（ごめんなさい）


若干の焦りを持ちつつ、ひとまず調べるとgithub上にissueがたってたので見てみることに

[Vs code can not open on Mac os catalina · Issue #82237 · microsoft/vscode · GitHub](https://github.com/microsoft/vscode/issues/82237)

中身を見てみると、Catalinaにアップデートしたけど、vs codeが開けない人が他にもいたんですね汗

ひとまずここから解決策があったみたい
[Investigate: macOS notarization · Issue #74782 · microsoft/vscode · GitHub](https://github.com/microsoft/vscode/issues/74782)

## 解決策
- システム環境設定から`セキュリティーとプライバシー`を選択
- `一般`から下にある、`ダウンロードしたアプリケーションの実行許可`から`このまま開く`ボタンをクリック

- ひとまずvs codeが起動できることを確認

要はvs codeが開発元が確認できないためにブロックされていたようですね

## 最後に
Catalinaになったばかりで解決策が英語しかないのが多いので、少しでも参考になれば幸いです。
Rust製RSS検索ツール

前にPythonで複数のRSSフィードを取り込んでキーワードと一致するものだけ表示するツールを書いたが、これをRustで書き直してみた。

https://qiita.com/usop4/items/599aabd53f8a89251749

本来であればPythonでもmultiprocessingで並列処理したようなことは当然ながらRustでもできるはずだが、そのあたりは今回はパス。

serdeというRustのシリアライズ・デシリアライズを使って、キーボード入力に一致する場合のみ表示する簡単な作りとしている。


```rust
#[macro_use]
extern crate rss;
extern crate serde;
extern crate serde_derive;
extern crate serde_json;

use rss::Channel;
use std::io;

fn main(){
    println!("keyword:");
    let scan = std::io::stdin();
    let mut keyword = String::new();
    let _ = scan.read_line(&mut keyword).unwrap();

    keyword = keyword.trim_end().to_lowercase().to_string();

    let urls = [
        "https://note.mu/usop/rss",
        "https://gizmodo.com/rss",
        "https://www.cnet.com/rss/all/",
        "https://techcrunch.com/feed/",
        "https://news.ycombinator.com/rss",
        "http://feeds.arstechnica.com/arstechnica/index/",
        "http://feeds.mashable.com/Mashable",
        "https://hub.packtpub.com/feed/",
        "https://www.forbes.com/innovation/feed2/",
    ];
    for url in &urls {
        print_list_items(create_list(&url),&keyword);
    }

}

#[derive(Debug)]
struct FeedItem {
    title: String,
    link: String,
    desc: String,
    pub_date: String,
}

fn print_list_items(items: Vec<FeedItem>, keyword: &String){
    items
        .iter()
        .for_each(|item| print_item(item, &keyword))
}

fn print_item(item: &FeedItem, keyword: &String){
    let mut flag = false;

    if item.title.to_lowercase().contains(keyword){
        flag = true;
    }

    if item.desc.to_lowercase().contains(keyword){
        flag = true;
    }

    if flag {
        println!("{}",item.title);
        println!("{}",item.link);
        println!("");
    }
}

fn create_list(url: &str) -> Vec<FeedItem> {
    //println!("{}",url);
    let channel = Channel::from_url(url).unwrap();
    let items: Vec<FeedItem> = channel
        .items()
        .iter()
        .map(|item| FeedItem {
            title: item.title().unwrap().to_string(),
            link: item.link().unwrap().to_string(),
            desc: item.description().unwrap().to_string(),
            pub_date: item.pub_date().unwrap().to_string(),
        })
        .collect();
    items
}
```