読書メモ:webを支える技術(1)(2)

URL URN URI

URL(リソースの場所)、URN(リソースの名前)、URI(リソースの識別)

REST

REST・・・webのアーキテクチャスタイル(指針・作法・流儀、システムを設計するときの指針)

リソース

  • web上に存在する、名前(URI)をもったありとあらゆる情報のこと。
  • URIを使うことでプログラムがアクセスできるようになる。
  • 複数URIをもったリソースもある。
  • ひとつのリソースは複数の表現ができる。
  • リソースには状態がある。

クライアント/サーバー

  • ステートレスサーバー
    アプリケーション状態を保存しない
  • キャッシュ
    いちど取得したデータをクライアントで使い回す
  • 統一インターフェイス
    httpが8個のメソッドしかもっていないのとかがそれ
  • 階層化システム
    負荷分散したりできる
  • コードオンデマンド
    プログラムをサーバからクライアントへ落としてきて実行する(jsとか)

クールなURI

「クールなURIは変わらない」

  • 言語依存の拡張子を使わない
  • 実装依存のパス名を使わない
  • メソッド名を使わない
  • セッションIDを含めない
  • そのリソースを表現する

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

読書メモ:webを支える技術(3)

TCP/IPについて

インターネットのネットワークプロトコルは階層型になっている

  • ネットワークインターフェイス
  • インターネット層
    パケット単位でデータのやりとり。IPが相当する部分。データ送り出すことは保証するが、送り先に辿り着いたかの保証はしない。
  • トランスポート層
    TCPが相当するところ。データの転送の保証をする。接続先の相手にコネクションを貼ってデータの抜け漏れがないかチェックする。 どのアプリケーションにデータが渡るか決めるのがポート番号。
  • アプリケーション層
    メールやDNSやHTTPを実現するところ。

ソケット・・・ネットワークのデータのやりとりを抽象化したAPI


ステートレス

HTTPはステートレスなプロトコル

ステートレス ←→ ステートフル

  • ステートレスでは・・  - アプリケーション状態を保持しない

    • クライアントのリクエストメッセージに必要な情報をすべて含める(自己記述的メッセージ)
    • サーバ側のシステムが単純になる
    • でも毎回必要な情報を送るので送信するデータ量が多くなる
    • ネットワークトラブルが起きたときにリクエストが処理されたかわからないので通信エラーへの対処が必要  
  • ステートフル

    • 代表的なものにFTPがある
    • クライアントの数がふえると同期するサーバも増やさなくてはいけなくて大変

アプリケーション状態・・セッション状態(ログインしてからログアウトするまで)のこと


HTTPのメソッド8個

HTTP入門

POSTとPUT

どっちでもリソースの作成ができる。でも、クライアントがURIを決めたいときはPUTが適しているが そのURIが存在しているか調べたり、クライアントが内部実装を熟知していないといけなかったりするので 特別な理由がない場合はPOSTでリソース生成をしたほうがよい

べき等

冪等 - Wikipedia 「ある操作を1回行っても複数回行っても結果が同じであること」

  • GET HEAD ・・・ べき等 で 安全(通信エラーが起こっても結果がかわらない)
  • PUT DELETE ・・・ べき等
  • POST ・・・べき等ではなく安全でもない

POSTの誤用に注意

GET PUT DELETE で実現できる機能はべき等と安全性が利用できるのでなるべくそれで実現する


ステータスコード

クライアントの挙動を左右するのでステータスコードの選択は重要。

ステータスコードは先頭の数字で分類されている

  • 1** 処理中(クライアントはリクエストを継続するか再送信)
  • 2** 成功
  • 3** リダイレクト(レスポンスメッセージの locationヘッダを見て新しいリソースに接続する)
  • 4** クライアントエラー
  • 5** サーバーエラー

認証

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

読書メモ:webを支える技術(5)

リソース設計とは・・・

  • クライアントとサーバの間のインターフェイスの設計(どう分割するか?、どうURIで名前をつけるか?、リンクの関係をどうするか?)
  • webサービスとwebAPIをわけて考えない(どちらもweb上にあるリソースを提供するものなので)

設計手法

データをソースに分ける方法

  • 関係モデル(関係モデル - Wikipedia)RBDMS(関係データベース管理システム - Wikipedia)などのER図から考える

    • 中心になっているテーブルの一行をURIリソースとする
    • ひとつひとつのリソースがそれ自身で全て表現できるようにするために正規化は行わない
    • トップレベルリソースと階層構造は直接導出するのがむつかしいので別途ドキュメントなどを見ながら構造化させる
  • オブジェクト指向モデルのクラス図から考える

    • 下位・上位への参照・検索・リストの取得などのメソッドインスタンスをもったクラス図を考える
    • 主要なデータを表現しているクラスのインスタンスひとつひとつがURIになる
    • メソッドそのものをリソースにしない。処理結果をリソースとする
    • クラス間の構造を表現しているサブクラス・継承などはそのままリソースの階層として使えないか考える
  • 情報アーキテクチャ(よくわからなかったのでまたいつか・・)

書き込み可能なwebサービスを考えるとき

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

nature of code:今日の練習「遺伝的アルゴリズム」

See the Pen Genetic Algorithms(遺伝的アルゴリズム) by kanaparty (@kanaparty) on CodePen.

遺伝的アルゴリズムを使ってランダムな文字列から「音はしぐれか」 種田山頭火 - Wikipediaへ進化させる。

遺伝的アルゴリズム

ステップは大きく分けて3つ

  • 集団の生成
  • 選択
  • 生殖

これを繰り返して進化させていくアルゴリズム (「進化させていく」って表現でいいのかしらと思ったら本には「特定の問題を解決することを意図して実装される」と書いてあった。 遺伝的アルゴリズム - Wikipedia wikipediaでは「解を探索する」と書いてあった。) 解は決まっていて、そこまでたどり着くための手法。 この経過の様子を眺めているのが結構楽しい。

ダーウィン自然選択説

遺伝的アルゴリズムを実装するときに必要な、ダーウィンの進化論の中核の3つの要素

  • 遺伝  子が親の性質を受け継ぐ
  • 変異  集団に多様な形質があるか、突然変異しないとすべての個体が同じ形質になってしまって進化が止まる
  • 選択  適者生存。自然選択でいうところの環境に適している個体が生き残ること。解決したい解によって異なる。

集団の生成

初期化部分。 解、初期集団を生成する。 コードでいうとこの部分

//ターゲット句
var target = 'おとはしぐれか';
//集団の初期化
var population = new Population();
population.init();

//個体
class DNA{
  constructor(){
    this.genes = [];
    this.fitness = 0;//適合度
  }
  //初期化
  init(){
    for (var i = 0; i < targetLength; i++) {
      this.genes[i] = String.fromCharCode(Math.floor(Math.random() * 81) + 12354);
    }
  }
}

//個体群
class Population{
  constructor(){
    this.List = [];
    this.length = 100;
    this.children = [];
    this.finished = false;
  }
  init(){
    for (var i = 0; i < this.length; i++) {
      this.List.push(new DNA());
      this.List[i].init();
    }
  }
}

目指す句の文字列を決めて、ランダムな文字列の句の集団を100個作る。

選択

今回は7文字の文字列が「おとはしぐれか」に近いものをより選択しやすくする状況を作る。 選択するときは、一致している具合に応じた数(適応度が高ければ多く、低ければ少ない)親を入れ物(配列)にコピーしていれておいて そこから次の世代の親を2つ拾うようにする。 結果的に適応度が高い個体が選ばれやすくなる。

適応度に応じてプールにいれているところ↓

//プール
var matingPool = [];

//個体
class DNA{
  //適合度をはかる
  calcFitness(){
    var score = 0;
    for (var i = 0; i < targetLength; i++) {
      if(this.genes[i] === target.charAt(i)){
        score++;
      }
    }
    this.fitness  = score / targetLength;
  }
}
//個体群
class Population{
  //淘汰
  naturalSelection(){
    matingPool = [];

    for (var i = 0; i < this.length; i++) {
      this.List[i].calcFitness();
      var fitness = this.List[i].fitness;
      //完全一致していたら止める
      if(fitness === 1){
        this.finished = true;
      }
      //適応度に応じた数をプールに入れる
      for (var j = 0; j < count; j++) {
        matingPool.push(population.List[i]);
      }
    }
  }
}

生殖

親をプールから選んで次の世代を作っているところ

//個体群
class Population{
  createNextGenelation(){
    //プールから親二つを取り出す
    for (var i = 0; i < this.length; i++) {
      var parentA = matingPool[Math.floor(Math.random() * matingPool.length)];
      var parentB = matingPool[Math.floor(Math.random() * matingPool.length)];
      //生殖(突然変異含む)
      this.children[i] = parentA.crossover(parentB);
    }
  }
}

//個体
class DNA{
  //交配
  crossover(partner){
    var child = new DNA();
    var midpoint = Math.floor(Math.random() *  targetLength);
    var mutate = (Math.random() < 0.1) ? true : false ;

    //突然変異
    if(mutate){
      child.init();
    }
    else{
      for (var i = 0; i < targetLength; i++) {
        if(i < midpoint){
          child.genes[i] = this.genes[i];
        }
        else{
          child.genes[i] = partner.genes[i];
        }
      }
    }

    return child;
  }
}

という感じでこれを繰り返すといつか「おとはしぐれか」になる!

nature of code:今日の練習「木(L-systemを使って)」

See the Pen tree(L-system) by kanaparty (@kanaparty) on CodePen.

L-systemを使って、藻みたいな描写をする課題。
L-system - Wikipedia

フラクタル構造を管理するメカニズム。必要な要素は3つあって、

  • アルファベット
  • 公理(初期状態)
  • 規則

作ったL-systemのところはこんな感じ

//L-system
class Lsystem {
  constructor(axiom, rule) {
      this.rule = rule;
      this.sentence = axiom;
      this.generation = 0;
    }
    //次の世代の文字列を作る
  generate() {
    var nextgen = "";
    for (var i = 0; i < this.sentence.length; i++) {
      var crr = this.sentence.charAt(i);
      for (var j = 0; j < this.rule.length; j++) {
        var a = this.rule[j].getA();
        if (a === crr) {
          nextgen += this.rule[j].getB();
        } else {
          nextgen += crr;
        }
      }
    }
    this.generation++;
    this.sentence = nextgen;
  }
  getSentence() {
    return this.sentence;
  }
  getGeneration() {
    return this.generation;
  }
}

//ルール
class Rule {
  constructor(chr, sentence) {
    this.a = chr;
    this.b = sentence;
  }
  getA() {
    return this.a;
  }
  getB() {
    return this.b;
  }
}

書いていくときにはタートルグラフィックという描画フレームワークを使うのが一般的。
F G + - [ ]などは亀(ポインタ)にだす直進、回転、などの指示のこと。
今回書いたのでいうとここのぶぶん

//描写
class Turtle {
  constructor(todo, length, theta) {
    this.sentence = todo;
    this.length = length;
    this.angle = theta;
  }
  draw() {
      for (var i = 0; i < this.sentence.length; i++) {
        var chr = this.sentence.charAt(i);
        switch (chr) {
          case 'F':
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.lineTo(0, -this.length);
            ctx.stroke();
            ctx.closePath();
            ctx.translate(0, -this.length);
            break;
          case '+':
            ctx.rotate(this.angle);
            break;
          case '-':
            ctx.rotate(-this.angle);
            break;
          case '[':
            ctx.save();
            break;
          case ']':
            ctx.restore();
            break;
          default:
        }
      }
    }
    //長さを変更
  changeLength(ratio) {
      this.length *= ratio;
    }
    //新しい文字列を取得
  updateSentense(axiom) {
    this.sentence = axiom;
  }
}

初めて知ったLOGO言語  

LOGO - Wikipedia www.wizforest.com

ポインタを亀にみたたて動かすっていうのが面白いなぁと思ったら もともと教育のための言語なんですね。 LOGO開発者 シーモア・パパート

オブジェクト指向がタートル・グラフィックスに起源を持つことはよく知られている」 らしい。そうなんだ!

そしてこの連載がかなり面白い。また読む。

早過ぎた孤独な予言者 − @IT自分戦略研究所

nature of code:今日の練習「枝」

See the Pen tree(2) by kanaparty (@kanaparty) on CodePen.

木っぽいやつ

コッホ曲線を書いた時のようにベクトルオブジェクト(とそれをまとめるarraylist)でつくってみたのは↓ こっちは枝の長さが一定に短くなるようにしてます。

See the Pen tree by kanaparty (@kanaparty) on CodePen.

nature of code:今日の練習「コッホ曲線」

See the Pen KochLine(コッホ曲線) by kanaparty (@kanaparty) on CodePen.

これ コッホ曲線 - Wikipedia

今までは回転をさせる時、rotateでcanvasを回転させて描く、みたいなことばかりしかやっていなかったが
今回のをつくるのにあたって自作ベクトルクラスに回転させる機能を追加した。

    //回転
  rotate(angle) {
    var cos = Math.cos(angle);
    var sin = Math.sin(angle);

    var newX = this.x * cos - this.y * sin;
    var newY = this.x * sin + this.y * cos;
    this.x = newX;
    this.y = newY;
    return this;
  }

ので自作ベクトルクラスがちょっと長くなった

//ベクトル
class Vector {
  constructor(x, y) {
      this.x = x;
      this.y = y;
      return this;
    }
    //加算
  add(x, y) {
    if (x instanceof Vector) {
      this.x += x.x;
      this.y += x.y;
      return this;
    } else {
      this.x += x;
      this.y += y;
      return this;
    }
  }
  static add(vectorA, vectorB) {
      var x = vectorA.x + vectorB.x;
      var y = vectorA.y + vectorB.y;
      return new Vector(x, y);
    }
    //減算
  sub(x, y) {
    if (x instanceof Vector) {
      this.x -= x.x;
      this.y -= x.y;
      return this;
    } else {
      this.x -= x;
      this.y -= y;
      return this;
    }
  }
  static sub(vectorA, vectorB) {
      var x = vectorA.x - vectorB.x;
      var y = vectorA.y - vectorB.y;
      return new Vector(x, y);
    }
    // ベクトル乗算
  mult(n) {
    this.x = this.x * n;
    this.y = this.y * n;
    return this;
  }
    //ベクトル除算
  div(n) {
      this.x = this.x / n;
      this.y = this.y / n;
      return this;
    }
    //ベクトルの大きさを返す
  mag() {
      return Math.sqrt(this.x * this.x + this.y * this.y);
    }
    //正規化する
  normalize() {
      var size = this.mag();
      if (size === 0) {
        return this;
      }
      this.x = this.x * (1 / size);
      this.y = this.y * (1 / size);
      return this;
    }
    //最大値
  limit(max) {
      if (this.mag() > max) {
        return this.normalize().mult(max);
      } else {
        return this;
      }
    }
    //回転
  rotate(angle) {
    var cos = Math.cos(angle);
    var sin = Math.sin(angle);

    var newX = this.x * cos - this.y * sin;
    var newY = this.x * sin + this.y * cos;
    this.x = newX;
    this.y = newY;
    return this;
  }
    //ベクトルの角度を返す
  static angle(vectorA) {
      var theta = Math.atan2(vectorA.y, vectorA.x);
      return theta;
    }
    //長さ1のランダムな値を返す
  static random2D() {
      this.x = (Math.random() * 2) - 1;
      this.y = (Math.random() * 2) - 1;
      return this.normalize();
    }
    //角度から長さ1のベクトルを返す
  static fromAngle(angle) {
      return new Vector(Math.cos(angle), Math.sin(angle));
    }
    //同じ値をもったVectorを返す
  static copy(vectorA) {
      return new Vector(vectorA.x, vectorA.y);
    }
    //ベクトル内積
  static dot(vectorA, vectorB) {
      return vectorA.x * vectorB.x + vectorA.y * vectorB.y;
    }
    //ベクトル間の角度を返す
  static angleBetween(vectorA, vectorB) {
    var theta = Math.acos((this.dot(vectorA, vectorB)) / (vectorA.mag() * vectorB.mag()));
    return theta;
  }
}