ひよこの外部記憶

めもおきば

「達人に学ぶSQL徹底指南書」ふりかえり

この本読んで思ったことや大事だと思った箇所のメモ
例題や問題とその意図を記載することにより、後から理解しているか、覚えているかを確認する意図で記載していく

www.shoeisha.co.jp

書籍を読んで思ったこと箇条書き

  • この本はSQLの研修を受けて、仕事でも使ってるけどなんか良く分からんみたいな人には結構オススメ
  • WINDOW関数についてそろそろ学ばなきゃ、みたいに思ってる人にもオススメ
  • WINDOW関数は普通のプログラミングの見方を持っていると、他の書き方よりもとっつきやすい
  • さよなら相関サブクエリ、こんにちはWINDOW関数
  • CASE式の強力さに触れられる
  • 集合論からみたSQL, 述語論理からみたSQL
  • 他の言語以上に闇が深いSQLのNULL

1章 CASE式のススメ

所感

  • CASE式すごい
  • SQL自体は見やすくはならないかもしれないが、SQLである程度フォーマットしたりする必要がある時のため覚えておきたい
  • DECODE使う必要はほぼ無い

要約

  • CASEは文ではなく「式」
    • 列名や変数を書ける場所ほぼ全てに書ける
  • 実装非依存かつ高い表現力を持つ

コード体系の変更

  • 選択したい行の形をCASEを用いて表現する
  • SELECT句とGROUP BYに同条件を指定すると実現可能
    • (SQLの範囲で取りたい断面で情報の取得が可能)

1. 行持ちを列持ちに

  • 集約関数の引数にCASE式で条件に当てはまるものだけ対象にする
  • SELECT句に別名をつけて、GROUP BYで使える実装もある
pref_name sex population
徳島 1 60
徳島 2 40
香川 1 100
香川 2 100
・・・ ・・・ ・・・

pref_name
徳島 60 40
香川 100 100
・・・ ・・・ ・・・

2. 表のクロス表作成

  • 以下の2表からクロス表作成
  • CASE式の条件をサブクエリで実現する

CourseMaster

id name
1 SQL入門
2 財務知識
・・・ ・・・

OpenCourses

month id
201806 1
201806 3
201806 4
201807 1
・・・ ・・・

クロス表

コース名 6月 7月 8月
SQL入門
・・・ ・・・ ・・・ ・・・

3.CASE式の中で集約関数

  • 1つのクラブのみに所属している人はHAVING, 複数の場合はmain_clug_flgで選択可能
  • CASE式の中で集約関数を使えば、HAVING句を書かなくても同等の処理が出来る
std_id club_id club_name main_club_flg
100 1 野球 Y
100 2 吹奏楽 N
200 2 吹奏楽 N
200 3 バドミントン Y
200 4 サッカー N
300 4 サッカー N
400 5 水泳 N
500 6 囲碁 N

std_id main_club
100 1
200 3
300 4
400 5
500 6

2章 必ずわかるWINDOW関数

所感

  • 相関サブクエリより読みやすいしパフォーマンスも良い
  • 一部が実行出来るの大きなメリット、仕事でもガンガン使っていきたい
    • 少し古いバージョンのPostgresql使っていると機能足りなかったりする
    • mysqlは対応が遅いため、なにか足りなかったりすることが多い(らしい)

要約

  • 主要なRDBMSがWINDOW関数を実装した
  • WINDOW関数の機能は以下のように説明出来る
    • PARTITION BY句は集約しないGROUP BY、レコード集合のカット
    • ORDER BY句によるソート
    • フレーム句によるレコードを中心としたサブセット定義

3章 自己結合の使い方

所感

  • 集合を作るために自己結合を活用する、という観点は興味深い

要約

  • マスタの組み合わせを得たい時など、重複順列、順列、組み合わせを自己結合で実現出来る
  • 重複の排除(DELETE文の利用)も自己結合を上手く使うと実現可能
    • rowid使って1つだけ残すような感じ
  • 自己結合を非等値結合と組み合わせて使う
    • 部分的に不一致なものを取得する
    • 同じ値段のもの(=名前が違うもの)みたいな感じで取れる
  • GROUP BYと組み合わせると再帰的集合を作ることが出来る

4章 3値論理とNULL

所感

  • 第一版を読んだ時に最も印象に残った章
  • unknownという地獄
  • NULLは使わないようにしたい、と思うけどまぁどうでも良いところには使ってしまう
  • NOT NULL制約は付けられる場合には付与すべきと思わされる

要約

  • NOT INとNOT EXISTSでは同値変換出来ない

    • NULLが入ると、NOT INは条件がunknownになる
    • EXISTSはtrueかfalseかのどちらかしか返さない
  • 極値関数を使うと、NULLが入っていてもうまく無視してくれる

    • MAXに (1 ,3 , NULL)と入ってきたら3が返る
    • 空集合が渡された時には極値関数の結果はNULLになる

5章 EXISTS述語の使い方

所感

  • 2回目読んだ中で一番印象的な章の一つ
  • この章、SQL本として有用なのはもちろんだが読み物としても面白い
  • 全称量化に気づくのがまずムズイ

要約

  • データベースにおける行はデータでなく命題
  • 述語とは戻り値が真理値になる関数
  • EXISTSは二階の述語
  • データが無い行、というような条件を探す場合には、理想的な状態(=全部入りの状態)をCROSS JOIN等 で作成し、そこからNOT EXISTSなり、EXCEPTなりで絞り込む
  • 全称量化「全ての行について〜」を「〜でない行が1行も存在しない」に置き換える
  • 列方向への全称量化、存在量化は対応する関数がある

テストの点数条件絞り込み

std_id subject score
100 算数 100
100 国語 80
100 理科 80
200 算数 80
200 国語 95
300 算数 40
300 国語 90
・・・ ・・・ ・・・
  • 全ての科目が50点以上の生徒を抽出
    • DISTINCTしない結果を考える、id300の国語は何故出力されないのか
  • 数学が80点以上、国語が50点以上の生徒を抽出
  • どちらも点数がある場合のみを条件に

6章 HAVING句の力

HAVING句は集合指向言語の観点から見ると強力
count()とcount(col_1)の結果は異なる
col_1にNULLが入って居た場合にはカウントされないが
の場合は例え1列しかなくてもカウントされる

GROUPに1種類しか存在しない、を表現する場合には以下の3種類の方法がある

1. NOT EXISTSで書く
2. HAVINGで特性関数のようなものと個数を比較する
3. HAVINGで評価したい値のMAXとMINが一致する

GROUP内に重複が無いもの、を表現する場合には対象列の個数と対象列をDISTINCTした結果が一致するかを比較する

バスケット解析 item | item | |:-------| |ビール| |紙おむつ| |自転車| |・・・|

ShopItem | std_id | subject | |:-----------|:------------:| |仙台|ビール| |仙台|紙おむつ| |仙台|自転車| |仙台|カーテン| |東京|ビール| |東京|紙おむつ| |東京|自転車| |大阪|テレビ| |大阪|紙おむつ| |大阪|自転車|

  1. Itemに含まれるものを全て取り扱っている店舗を取得
  2. 取り扱っているものが過不足なくItemの項目と一致する店舗を取得

Slackで二要素認証用のデバイスが死んで、パスワードも忘れ、リカバリコードも失った時の復旧方法

管理者に連絡すれば良いと思ったが、スマホを失うと連絡する方法が無かったりする

この方法で復旧できる前提

  • ログインしようとしているSlackワークスペースがfree plan もしくは有償プランでも二要素認証が強制されていないワークスペース
  • どこかのPCでログインセッションが生きている
  • リカバリコードを使い切っていない

この条件を満たす場合上記管理者に連絡せずに復旧できる(2018年8月現在)

手順

  1. 自分のユーザーアイコン > Open account settings > Accountページ
  2. Two-Factor Authenticationのexpandボタンクリック
  3. You have 10 unused backup codesからリカバリコードをコピー
  4. Passwordのexpandボタンクリック
  5. Reset your password by Email
  6. mailから、新しいパスワードと共に二要素認証のコードを求められるので、上記のリカバリコードを入れてパスワード変更
  7. パスワードを更新したらdisable Two factor authentication から一度二要素認証を無効にする
  8. 直後に再度 Enable Two factor authenticationから、新しいデバイスで再度二要素認証を有効にする

スマホが海にダイブして、一番不安になったのはSlackにログイン出来なくなったことでした
とりあえず検索でこんな記事が有用になっちゃったあなたは悪いことは言わないからAuthyを使おう

authy.com

リカバリコードさえどこにあるか分からん時点で君はまた携帯壊すって

Spring Boot(Gradle)プロジェクトをIntelliJ Community Editionで起動するまで

はじめに

IntelliJ Community EditionでGradleプロジェクトのSpring Bootを取り込む方法が見つけられなかったのでまとめた

普段仕事ではEclipse使っているが、Eclipseだけ使っていると

これじゃない気がするが、あるべき姿が良くわからない

という問題に陥る
IntelliJを使うことでこの問題解消出来たら良いな

Java

MacだとWindowsと違いすぎて不安になる
とりあえず最新で入れた

.bash_profileには以下のような感じで

export JAVA_HOME=`/usr/libexec/java_home -v 10`
$ java -version
java version "10.0.1" 2018-04-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)

Java10にしてみた

Spring Boot(ver. 2.0.3)

Spring Initializr

まずはSpring Initializrで色々入れる、知っているやつ色々入れてみた

IntelliJ(Version 2018.1.5)

基本的に設定はデフォルト、Use auto-import だけonにしている
f:id:ura_ra:20180710001131j:plain Gradle wrapper(= gradlew)を使用
Gradleが使うJavaをJava10に変更

アプリ起動

ヘッダーのRun > Run

デフォルトのアプリ動かすだけで割と時間を食ってしまった...
IntelliJはTipsとか見ながら慣れていくことにする

その他

上記構成だと起動は出来るが起動時に以下の警告が出る Spring coreで不適切なリフレクションを使っている? 家で遊ぶだけだからとりあえず放置

2018-07-08 00:02:09.802  INFO 10799 --- [           main] o.s.i.config.IntegrationRegistrar        : No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created.
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (file:/Users/urara/.gradle/caches/modules-2/files-2.1/org.springframework/spring-core/5.0.7.RELEASE/54b731178d81e66eca9623df772ff32718208137/spring-core-5.0.7.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

RSpec備忘録

この記事の目的

  • rspec 3.1の書き方に慣れる
  • 今度使う時のリファレンス用

今回使うバージョン

今回のタスク

1行に1つの整数が入っているファイルを読み込んで

  • 和を出したり
  • 平均出したり
  • 新たな配列作ったり

実際のコード

urara/scorespec(Github)

手順メモ

いつものプロジェクト準備

spec書く前作業

bundle init # Gemfileにrspec取る記述
bundle install

rspec --init # .rspecに「-format d」追記(個人的な好み)

mkdir spec/

TDD始める

  • spec/score_spec.rbから書く
    • ファイル読み込んでscoreオブジェクト作る
    • scoreが持つべき関数を呼ぶようなテストを書く
    • rspec実行、テストこけるの確認
    • score.rbファイルにScoreクラス作り、メソッド定義のみ
    • テスト通るの確認
    • またテスト足す
    • こけるの確認
    • 実装
    • 。。。(繰り返し)

書き方関連

it とspecify

参考: るびま

  • どうやらitは過去specifyを使っていたらしい
  • specifyは今も有効
  • itだと日本語だと違和感があるのでspecify使った物も多い
  • 個人的には
    • type数が少ないitで良い
    • 混ざる位なら全部itで良い

describeとcontext

参考: るびま

  • contextはdescribeのエイリアス
  • describeはネスト出来る
  • describeはテスト対象を表し、contextはテスト状況を表す
  • Githubのscore#get_multi_array参照

アンダースタンディングコンピューテーション 2章

下の書籍2章の話

https://www.amazon.co.jp/dp/487311697X

※ 読んでる時に書いたメモです、アンダースタンディングコンピューテーションを要約するようには書いていません。

第一部 プログラムと機械

計算

計算には以下の要素が必要

  • 計算を行う機械
  • 機械が解釈できる言語
  • 言語によって書かれる実行すべき計算を表すプログラム

意味論とは?

言葉と意味の関係に関する学問

形式的意味論

プログラミングの意味を明確にし、プログラミングに関する興味深い事を発見する
→ 数学のトポロジーみたいな感じかな?

プログラミング言語の仕様を完全に記述するには

  1. 構文(どのように見えるか)
  2. 意味論(何を意味するか)

が必要

プログラミングの言語の仕様

実装による仕様

Rubyもこれ
MRI(Matz's Ruby Interpreter)によって定義、JRubyMacRuby等はMRIの振る舞いと完全に一致する必要がある

公文書による仕様

JavaECMAScript
専門家によって十分に議論されたドキュメントにより仕様を定義

形式意味論による仕様

数学的手法によりプログラミング言語の意味を正確に記述する

構文とは?

特定の言語により有効なプログラムであるかを判定する規則
→パーサにより判断

パーサの役割はASTを作成する事
= 構文上問題ない場合(ASTが問題なく作られる場合)でもプログラムとしては問題がある状態がある

# AST作れるけど、プログラム的には問題がある例
y = x + 1

操作的意味論

  • プログラムがある種のプログラム上でどのように実行されるのか、規則を定義する
  • プログラム言語毎に異なる抽象機械が必要

スモールステップ意味論

  • 構文を小さなステップに簡約することで、プログラムを評価する機械を考える
    • 評価出来る部分から評価する

四則演算のふるまい記述

class Number < Struct.new(:value)
  def to_s
    value.to_s
  end

  def inspect
    "<<#{self}>>"
  end

  def reducible?
    false
  end
end

class Add < Struct.new(:left, :right)
  def to_s
    "#{left} + #{right}"
  end

  def inspect
    "<<#{self}>>"
  end

  def reducible?
    true
  end

  def reduce
    if left.reducible?
      Add.new(left.reduce, right)
    elsif right.reducible?
      Add.new(left,right.reduce)
    else
      Number.new(left.value + right.value)
    end
  end
end

class Multiply < Struct.new(:left, :right)
  def to_s
    "#{left} * #{right}"
  end

  def inspect
    "<<#{self}>>"
  end

  def reducible?
    true
  end

  def reduce
    if left.reducible?
      Multiply.new(left.reduce, right)
    elsif right.reducible?
      Multiply.new(left, right.reduce)
    else
      Number.new(left.value * right.value)
    end
  end
end

同様な感じで他の四則演算記号や"<"やBool値等も作れる

変数

変数の機能を持つためには、仮想機械は現在の式の他に環境(environment)を持つ必要がある
→#reduceをenvironmentを引数に取るように変更、仮想機械は自身の式の中に変数が出てきたらenvironmentを探して簡約する

こんな感じ

class Variable
  def reduce(environment)
    environment[name]
  end
end

# 各#reduceは以下の様な感じに変更
def reduce(environment)
  if left.reducible?
    Add.new(left.reduce(environment),right)
  end
  ・・・
end

if文

こんな感じ

class If < Struct.new(:condition, :consequence, :alternative)
・・・
  
  def reduce(environment)
    ・・・
    case condition
    when Boolean.new(true)
      [consequence, environment]
    when Boolean.new(false)
      [alternative, environment]
    end
  end
end

while文

if文に置き換える事で解決 こんな感じ (SequenceとDoNothingは書籍参照)

class While < Struct.new(:condition, :body)
  ・・・
  def reduce(environment)
    [If.new(condition, Sequence.new(body, self), DoNothing.new), environment]
  end
end

ビックステップ意味論

  • ビックステップはASTを一度走査することで、どうやってプログラム全体の結果を計算するかを記述
  • スモールステップよりも大雑把な感じ(再帰で一片に解決する)

※載せると長くなるので省略

OCamlのコア言語はビックステップで説明されている

式と文

  • 文はそれ単体で完結する → 評価された時に戻り値を捨てる
  • 式は何かの一部 → 評価された時の戻り値を使う

だから、SQLのCASE式というのは評価され何かに置き換わる →どこにでも書ける

  • RubyPythonの違いは式と文の違いがあるかどうか(るびま)
    • 例えばa=1とかは文であるが、Rubyは戻り値を返す、Pythonは式を書くべき箇所に文を書くとエラーになる

  • 評価されることで別の式を生成
    • スモールステップではreduce出来ない所までreduceする
  • 式をreduceして新たな式を作る、これをreduce出来ない所まで繰り返す
  • 今までやっていた例は全ての部分が式

評価されることで抽象機械のenvironmentを変更

代入では

x = x + 1

の場合、右辺が式、全体は文になる

  • 文の評価は、右辺がreduce出来るか見て、出来ればreduce、出来なければ代入を行う
  • 文の評価によって、初めて状態が変更される

表示的意味論

  • プログラムをネイティブ言語から別の表現に変換
    • Rubyで書くとこんな書き方〜」

walkの意味を伝える場合 - 実際に歩いてみせる(操作的) - 「歩く」の英語表現、等と既に知っているであろう知識とマッピングする(表示的)

  • Rubyで実装する場合には、ASTが意図した意味を表現するRubyコード文字列に変換する事
    • procオブジェクトを作る感じ

Rubyで書いたため実行可能であるが、例えば「数式」「英語」等で表される場合にはもちろん無理

まとめ的なもの

今までの動作の違い

今までの違いを見るにはwhileの動作を見るとわかりやすい

スモールステップ意味論のwhile

  • 抽象機械の簡約規則として書かれる
    • ループとしての振る舞いは出てこない スモールステップ意味論から言語を理解するには、スモールステップ規則を全て調べ、それがどのように作用するか見る

ビックステップ意味論のwhile

  • 最終的な環境を直接計算する方法が書かれる
    • どのように振る舞うかはWhileの記述を見ればわかるが、これを見ただけでは環境がどのように変更されるか等が分からない

表示的意味論のwhile

実際の形式意味論

形式意味論の重要な応用は

  • 「実装による仕様」等の非形式的仕様に頼らない、あいまいさのない仕様を与えること
  • 言語の一般的な特性及び具体的なプログラムの特性を証明すること
  • 振る舞いを変えることなく効率をこうじょうさせるようプログラムを安全に変換する方法を見つけること

  • 操作的意味論はインタプリタの実装に密接に関係するため、言語の正当性を証明出来る

  • 表示的意味論はプログラムの実行方法を無視して別の表現に変換する方法に着目している、これは、コンパイラが行う動作に近い

【Ruby】UTF-16でエンコードされたファイルを扱う方法

#UTF-16エンコードされたファイルをUTF-8に変更する方法について
Ruby 2.0.0-p247で動作(どのバージョンから動くのかは調べていない)
調べるとiconvを使う方法やnkfを使う方法等情報が混在していたため、備忘録がてらまとめておく


以下の例では、ディレクトリ以下にある全てのUTF-16エンコードされたファイルをUTF-8に変更する。

def trans_utf8(path)
   Dir::glob(path).select{|item| File.file?(item)}.each do |file|
     File.open(file, 'r'){ |f| 
       buffer = f.read();
       buffer = buffer.encode("UTF-8", "UTF-16", :invalid => :replace, :undef => :replace, :replace => '*')
       f = File.open(file, 'w')
       f.write(buffer)
     }   
   end 
end

fileもう一回開きなおしたらclose要るのかな?確認する。

パーフェクトRuby 2章

#第二章
簡潔にまとまってるのでreferenceに良いかも、忘れた頃にもう一回読んでも良いかも

以下、曖昧だった箇所、初めて知った事


##スコープ
### ローカル変数

  • JavaScriptを弄った後いつも混乱するからまとめ
  • Rubyのスコープはブロック > メソッド定義 > クラス定義 > トップレベルで作られる
  • ローカル変数はスコープ毎に定義され、外の変数は見えない(こうあるべきよね)
  • ブロックのみ例外で、外にあるローカル変数触れる

※外からブロック内に定義されたローカル変数には(もちろん)触れない

##真偽値

  • Rubyではfalseとnilのみが偽、他は全て真
  • JavaScriptのようにundefinedとnilの区別が無いため、例えば配列の要素取り出したらnilだった場合

1.何も入らなかった
2.入っていた値がnilだった
の切り分け作業が発生する。
というかそんな切り分けが起きないようにコーディングしましょうっていう事(なんでしょうきっと)

##self

  • Rubyのselfはインスタンス自身を返す(Java等のthisと同じ)
  • クラス内でレシーバを書かずメソッド名を書いた場合selfがレシーバとなる
  • 基本的にselfは書かなくて良いが、インスタンス変数への代入では、selfを書かなかった場合、ローカル変数宣言になってしまう

##Arrayの宣言
%i(red green blue) #=> [:red, :green, :blue]と一緒
※Ruby2.0から

##多重代入
これを使うと変数の交換が以下の記述でいける
a, b = b, a

##自己代入
Rubyに無いと思ってた、なんでだろう?
a ||= 2
と書くとaがnilまたはfalseであった場合aに2を代入という意味
nullチェックが簡単に書ける、と