iq29 diary

EG.LAB 開発日記

宇野常寛 『雑誌の作り方特別講義』まとめ

宇野常寛 『雑誌の作り方特別講義』

行ってきたのでコンテキスト無視の自分解釈でまとめてみた。
なのでニュアンスとか本人の意図と違うところがあるかも。 ご了承ください。

雑誌

雑誌の役割

  1. 人々のライフスタイルを投影
  2. 世界観の提示

雑誌の性質

  • 雑誌は興味があるものからないものへ伝搬させる性質がある
  • スマホだと自分が興味あるものだけで、雑多なコンテンツに出会わなくなってしまう
  • 雑誌が一番ブランディングしやすく、手っ取り早く世界観を伝えやすい
  • 雑誌は自己表現や自己実現の手段であるべき

人間のバイオリズム、技術進歩によって雑誌は衰退する運命にある

  • サブカルに強くなるため雑誌で情報収集される時代があった
  • スマホ等の登場により、Web 媒体に先を越されてしまうようになった
  • 今となっては週刊、月刊のペースでは情報が古すぎる
  • 宇野氏が責任編集している PLANETS は約 1 年おきに刊行されている

政治 → 文化 → 経済 (今ここ)

  • かつての政治、サブカルに強い奴がマウントを取れる時代は終わり、起業家や Tech に強い奴が物事を語るようになった
  • 国家権力こそ未だ圧倒的だが、私企業の経済成長によって容易に法律と世の中が変わってしまうようになった

他誌

  • サラリーマンのコンプレックスにつけこんだのが NewsPicks
  • 頭が良いことを誰にでも伝わるように噛み砕くのがほぼ日
  • 赤字を出すルサンチマンヘイト本やコンプレックス商法に依存しないで、リクームできる付加価値のある本を高い値段で売れるようにしていくべき

Planets

  • 雑誌そのものが売れなくてもそのブランドを作ることに意味がある
  • 読者の感度と偏差値が高いものをつくる、あえて噛み砕かない内容にする
  • 自分が読みたい雑誌は自分でお金を出して作ればよいと考えた
  • 仮に自分ならこうするという建設的な対案を書きたかった
  • 書籍だと相応の期待に応えないといけないのでハードルが高い
  • web マガジンともいずれ連動させる

現代の人々が求めているのはリアルタイムか時間をかけた超大作

  • 月刊誌、週刊誌の需要は無くなってきている
  • 逆に半年、年一冊だけ刊行されるスペシャルな総合雑誌であれば手に取られる可能性がある

Planets 10 号

戦争について

  • 書きたいテーマとはいえ、部数が落ちることがハッキリと分かっていた
  • 10 号という節目で過去の号の特集を今やったり・過去の自分がやりそうなことも企画したが、結局今やりたいことを選んだ
  • キャッチーな導入にして、目次を作り、本題に戦争というテーマを持ってきているが、通して読むと流れが繋っている
  • 顔である猪子寿之と落合陽一を最初と最後に持ってきた

表紙、デザイン

  • 俯瞰してる、圧倒的に美しいものという意味で衛星写真の表紙に決まった
  • 読み進めると視点が落ちてくるという写真コンセプトになっている
  • SNS アイコンのようなフラットな表紙ロゴ。中身は多様なコンテンツという性質上、表紙は入っていきやすいデザインにしている
  • イラストは基本的に使わない。発注の仕方で素材がピックできてしまうと Controllable で、ありのままではないので好まない
  • イラストが一部にあるのはそこだけ外注しているため

座談

  • 対話はクオリティーコントロールが難しい
  • 散文形式は編集が大変なのと読みにくいから会話調。時代のニーズにもあっている
  • 座談は各々がテーマに対して総論で Yes という立場であっても、各論で No を持っていないと成立しない

流通の優先順位

  1. BASE: ユーザーを囲って育てたかった。特典もつけた。利益率も9割ほどで高い。
  2. 信頼関係のある小売と書店
  3. Amazon: 利益率が低い

インタビュー

  • 肌感で潜在レベルで気付いているけど未だ言語化できていないことを引き出す

パトレイバー2

  • めっちゃ面白いらしい

30代だけど「20代エンジニアのためのプログラマー勉強法」 に参加したので Matz の話をまとめてみた

30代だけど「20代エンジニアのためのプログラマー勉強法」 に参加したので Matz の話をまとめてみた

20代エンジニアのためのプログラマー勉強法

2018/09/29
まつもとゆきひろ / Matz
質疑応答に使われたハッシュタグ: #プログラマー勉強法

背景知識の活用

勉強、メタファー、抽象化 して理解しやすいようにする。類似性からパターン抽出する

抽象化のデメリット

苦手克服 vs 得意を伸ばす

学生時代のテストなら点数の伸びしろがある苦手科目の克服が重要
しかし社会人の勉強に100点満点という上限がない
得意を伸ばすのが良い戦略。苦手があるのはよくないみたいな概念は無視せよ

その他、対立する概念

  • 記憶 vs 把握
  • 知識 vs インデックス
  • 試験 vs 常在戦場
  • 一次元 vs 多次元
  • メイン vs サブ
  • 間接的 vs 直接的
  • 安定 vs 変化

成功する確率を高める要素

  • 高評価
  • 尊敬される
  • 尊重される

大事なこと

内省 - self reflection

走り出すだすのはラク
続けるのは大変
走る前に考える
好きなものは上達が早い
苦手の克服に意味はない

パターン認識が成功の秘訣

尊敬する人は誰

身近な人を挙げる人
→ 良い面を見れる人

知らない人のことは尊敬できない

  • 尊敬: 人格も敬う
  • 尊重: ないがしろにしない、人格は無関係

人は本質的にミーハー。有名人だと得

  • 尊敬をしていなくても、知名度は価値と可換されている
  • 知られる必要がある
  • 有名だから成功する、成功したから有名になるわけではない
  • これって循環論法?

勉強はマーケティングと同じ

キャズム (峡谷) 理論

  1. イノベーター(Innovators:革新者、革新的採用者)
  2. アーリーアダプター(Early Adopters:初期採用者、初期少数採用者)
  3. アーリーマジョリティ(Early Majority:前期追随者、初期少数採用者)
  4. レイトマジョリティ(Late Majority:後期追随者、後期多数採用者)
  5. ラガード(Laggards:採用遅滞者、伝統主義者)

つまり

  • 知らないものを人は買わない
  • ニッチにまずは進出する
  • 次に横展開する
  • ユニークさ
  • 埋没しないことが重要

Matz がやったこと

  • 東京に住まない
  • 尊重してもらえる、埋没しない環境
  • 下のレイヤーに力を入れる。社内ツールの開発
  • 高い裁量権を持っていた
  • 周囲の生産を高めた
  • バブル崩壊後、社内ツールのメンテナー (閑職) になった
  • イヤな仕事はなかった
  • フリーソフトウェア: Ruby の開発して公開した。ユニークな存在になった
  • ニッチに進出、局所的な有名人になった
  • 時を超えて共通する問題、人間の性質やふるまいによって起きるコミュニティの問題を解決

どう勉強するか

パターン認識して抽象化する

  • 内省 / インベントリ / 棚卸し
  • 真剣に考える。しかし予想は外れる。決めたことは変えてもいい
  • 未来や将来のことは考えない。それよりも自分の傾向を考えるべき

モチベーション

  • 時間の使い方、それが自分にとっての優先順位を表す
  • 仕事中の時間の生産性を高めて、それを勉強とするのが理想
  • 短い時間で成果をあげる
  • 仕事には必ずバッファを入れる。割りこみタスクが入るのはザラであるため
  • 人生のバランスを考える。プライベートを犠牲にしない

アウトプット

  • インプットだけでは差別化要因にならない
  • 心理的障壁がある: アウトプットはしんどいし恥ずかしい
  • アウトプットによる定着、体系化を行う
  • クオリティは棚上げしてアウトプットを繰り返すと最適化される
  • いつか人間の可塑性が起きる
  • 人は置かれた環境に合わせて変化する
  • 35才で損益分岐点としてマネジメントに回されることがあるが、それが楽しくなる人もいる
  • 自分は固定的と思わない。ゆっくりだが環境によって変化する

基礎

コンピュータサイエンス
  • 定番知識や基礎を抑える
英語
  • 18億人と話せる
  • タイムマシン経営。海外で流行っていることが日本で適用できる
  • ガラパゴスを出る
  • 語学は場数でしかない
  • 完璧は目指さない
コンフォートゾーン
  • 幸せな空間だけにいると成長がない
  • 普段ならやらないことをすると成長機会がある
  • 変化を恐れない訓練をする
  • 他人は無責任である、という原則 を知っておく
誰かを見下さない
  • コミュニケーションができなくなる
  • 自分ことも卑下しない

質疑応答

影響を受けた本

情報収拾

アメリカで働きたい人へのアドバイス

  • H1B のビザをとるのが定石。会社紹介のビザなので現地企業に認めらないといけない
  • 英語で自分のスキルセット・実績をプレゼンできるようにする
  • ひたすらアプリを作りまくる人が多い

最後に

自分の人生を良くすることに貪欲になった方がいい
自分は運がよかったが運がいいかはわからないので貪欲になったほうがいい

Fork してから Pull Request するまで

Fork してから Pull Request するまで

# commit する前にブランチを切っておく
git checkout -b [新しいローカルブランチ名 ★1]

# git add する
# git commit する

git push origin [フォーク先の新しいリモートブランチ名 ★2]

#
# フォーク元のリモートリポジトリを登録
# 差分を取り入れてフォーク先 (origin/master) を最新化する
#

# まずフォーク元のリモートリポジトリを upstream という名前で登録する
git remote add upstream [フォーク元のリポジトリ SSH]

# ローカルを master ブランチに変更
git checkout master

# フォーク元の upstream から pull してローカルを最新化する
git pull upstream master

# ローカル の master ブランチでフォーク先 (origin) リポジトリに push
git push origin master

#
# ローカルブランチを変更して、master の最新差分を取り入れて push する
#

# ローカルブランチを変更する
git checkout [ローカルブランチ名 ★1]

# ローカルの master ブランチから rebase (コミットログが綺麗な merge )
git rebase master

# -f (force) フォーク先のリポジトリに強制的な push する
git push -f origin [フォーク先のリモートブランチ名 ★2]

これでフォーク先のリポジトリでは自分のコミットが先頭(最新)、かつフォーク元の差分も過去に反映 (Verified) されたことになっている。
この後は
1. Github でフォーク先の自分のリポジトリに行き、左側にあるボタンより branch を master から [フォーク先のリモートブランチ名 ★2] に切り替える。
2. 右上にある Pull Request ボタンを押して、Pull Request を送信する。

すれば OK

作業中のプルリクの場合

  • タイトルに [WIP] をつけて作業中であることを明記する

今更 ES2015 まとめた

今更 ES2015 まとめた

この記事を整形しただけです
ES2015について (ES6) · takahashiakira/tech_for_web Wiki · GitHub)

Class

ES5 における prototype 構文にあたる

class Greet {
  constructor(name) {
    // プロパティ
    this.name = name;
  }
    
  // インスタンスメソッド
  hello() {
    console.log('Hello, My name is ' + this.name)
  }
    
  // スタティックメソッド
  static create(name) {
    return new Person(name);
  }
}

var tom = new Greet('Tom');

// インスタンスメソッドの実行
tom.hello();

// スタティックメソッドの呼び出し
var john = Greet.create("John");

let

ブロックスコープ内のみで利用可能な変数定義。

var foo = 'foo';

{ // この foo は外の foo とはスコープが違うので別物
  let foo = 100;
}

let の宣言をブロックで囲めば、即時関数の中で private な変数を宣言する必要がなくなる

(function () {
  // private
  var food = 'Meow Mix';
}());

console.log(food); // Reference Error
{
  // private
  let food = 'Meow Mix';
}

console.log(food); // Reference Error

const

定数のため再代入できない

const foo = 100;
foo = 'foo' // error

配列は各要素のアドレスを保持しているだけなので、要素の値変更はエラーにならない

const arr = [1, 2, 3];
arr[1] = 10

Arrow Function

// ES5
var func = function (x, y) {
  return x + y;
}
// ES6
var func = (x, y) => {
  return x + y;
}

bind

bind は this の指す先を明示的に指定したオブジェクトに変更できるもので、イベントリスナーなどで this の中身が変わってしまう場合などに役に立つ。アロー関数内では this の値をバインドしなくても利用できる

// ES5
function Person(name) {
  this.name = name;
}

Person.prototype.prefixName = function (arr) {
  return arr.map(function (character) {
    return this.name + character;
  }.bind(this)); // bind しないと this.name が使えない
};
// ES6
function Person(name) {
  this.name = name;
}

Person.prototype.prefixName = function (arr) {
  // this.name をいきなり使える
  return arr.map(character => this.name + character);
};

Method

ハッシュ内のメソッドの function も省略できるようになった

// ES5
var counter = {
  count: 0,
  // メソッド
  increment: function () {
    this.count++;
  }
}
// ES6
var counter = {
  count: 0,
  // メソッド
  increment() {
    this.count++;
  }
}

Parameter

Rest Parameter

引数を可変長で利用できる

function rest (...rest){
  console.log(rest);
}

// 好きなだけ引数を渡せる
rest(1, 2, 3); // [10, 20 ,30]

Default Parameter

関数でデフォルトパラメータを指定できる

function add (a = 1, b = 2){
  return a + b;
}

Template Strings

テンプレートリテラル を利用して特殊文字エスケープする必要がなくなった
JavaScript の テンプレートリテラル を極める!

// バッククオート (`) で囲めば、ちゃんと " はエスケープされる
let text = `This string contains "double quotes" which are escaped.`;
var name = 'Bob';

// 文字列に変数を埋め込めるようになった
console.log('Hello, ${name}.');
// 改行に改行コードを使う必要がなくなった
let text = ( `cat
dog
nickelodeon`
);
let today = new Date();

// 式も文字列内で展開して扱えるようになった
let text = `The time and date is ${today.toLocaleString()}`;

Map

key-value データを扱うクラスである Map を利用できるようになった

var map = new Map();
map.set('key1', 'value1');
map.get('key1'); // "value1"
map.has('key1'); // true
map.delete('key1');
var map = new Map([['k1', 'v1'], ['k2', 'v2']]);
map.get('k1') // "v1"
console.log(map2.size); // 2
map2.clear(); // 全データのクリア

WeakMap

WeakMap は、Key に指定されたオブジェクトに対して弱い参照を持つことでガベージコレクションを妨げないクラスとなっている。そのため繰り返しを伴うメソッドや clear メソッドは存在しないが、キャッシュに利用したり、プライベートプロパティとして利用できる

const privateNames = new WeakMap();

class Foo {
  constructor(name) {
    // name をプライベートプロパティとして保持
    privateNames.set(this, name);
  }

  getName() {
    return privateNames.get(this);
  }
}

Symbol

オブジェクトプロパティのキーとして使うことができるユニークな値を生成。プロパティ名がコンフリクトしないことを保証できるため、文字通りシンボルとして使われるイベント名などの定数や列挙型の値として使うと便利

var syml = Symbol();
var syml2 = Symbol('foo');

syml2.toString(); // "Symbol("foo")"
console.log(syml2 === Symbol('foo')); // false

var obj = {[syml2]: 1};

Object.keys(obj); // []
Object.getOwnPropertySymbols(obj); // [Symbol(foo)]
var obj = {
  [Symbok.toStringTag]: 'Foo!'
}
console.log(String(obj)); // "[object Foo!]"

Object.assign(target, source1, source2...)

オブジェクトをターゲットにシャローコピーする。jQuery の $.extend と同様の機能。

var objA = {
 "key1": 1,
}

var objB = {
 "key1": 2,
 "key2": 2
}

// ObjA に objB の要素を上書きコピーする
var objC = Object.assign(objA, objB);

console.log(objA == objC); // true
console.log(objA["key1"] == 2); // true
console.log(objA["key2"] == 2); // true

String

String.includes(string)

文字列の中に引数の文字列が含まれているか真偽値を返す

const string = 'food';
const substring = 'foo';

console.log(string.includes(substring)); // true

String.repeat(n)

文字列を n 回繰り返す

'meow'.repeat(3); // 'meowmeowmeow'

Array

  • Array.from: Array のようなオブジェクトやイテレータを Array に変換
  • Array.of: 引数を要素に持つ配列を生成する
var arr = Array.from('foo');

console.log(arr); // ['f', 'o', 'o']
var arr = MyArray.of[1, 2, 3];

console.log(arr); // [1, 2, 3]
console.log(arr instanceof MyArray); // true

イテレータへの対応として、Map や Set と互換性のあるメソッド keys, values, entries が追加された。その他、配列内で要素をコピーするメソッド copyWithin や、要素を指定の値で埋めるメソッド fill や、find、findIndex が追加された

Promise

非同期処理を抽象化する統一的なインターフェース

// 非同期処理
function wait(time){
  // 引数名は自由
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // 処理が成功の場合、resolve の引数の中で then に渡される戻り値を書く
      resolve('wait: ' + time);
    }, time);
  });
}

// then 以下に resolove 時の処理。value で戻り値を受け取る
wait(2000).then(value => {
  console.log(value); // "wait: 2000"
// then をメソッドチェーンにすることもできる
}).then(value => {
  conosle.log(value); // undefined
});

Promiseのエラー処理

// 非同期処理
function getUrl(url) {
  return new Promise((resolve, reject) => {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.onload = () => {
      if (xhr.status == 200) {
        resolve(xhr.statusText);
      } else {
        // 処理が失敗の場合、reject の引数の中で catch に渡される戻り値を書く
        reject(new Error(xhr.statusText));
      }
    }
    xhr.onerror = () => {
      // 処理が失敗の場合、reject の引数の中で catch に渡される戻り値を書く
      reject(new Error(xhr, statusText));
    };
    xhr.send();
  });
}

getUrl('/items').then(res => {
  var items = JSON.parse(res);
  someProcess(items);
// catch 以下に reject 時の処理。e で戻り値を受け取る
}.catch(e => {
  console.error(e);
});

Promise.all

全ての非同期処理が終わるまで待つ

Promise.all([
  // 配列の中で非同期処理を複数実行
  getUrl('/foo'),
  getUrl('/bar')
]).then(res => { // 受け取る戻り値 res も配列
  console.log(res[0]);
  console.log(res[1]);
}).catch(e => {
  console.error(e);
});

co

Generator をベースにしたライブラリ。yield の処理が終わるまで次に進まない。非同期処理の可読性があがる

// ジェネレーター関数で非同期処理を実装
function * getFirstitem() {
  var Items = yield getUrl('/items');
  var item = yield getUrl('items/' + imtes[0].id);
  return item;
}

var co = require('co');

co(function* () {
  // try - catch 文
  try {
    var item = yield getFirstItem(); // ジェネレータ関数を同期処理として実行
    someProcess(item); // item の取得を待ってから実行される
  } catch(e) {
    console.error(e);
  }
});

Generator

処理を停止したり再開したりできる特殊な関数。yield で処理が一旦止まるので、next で次に進める

function* 宣言 (末尾にアスタリスクが付いた function キーワード)

Generator オブジェクトを返すジェネレーター関数を定義

function generator() {
  yield 1;
  yield 2;
  return 3;
}

var g = generator();

// generator1 の処理が全部終わったかどうかは done でわかる
conosle.log(g.next()); // {value: 1, done: false}
conosle.log(g.next()); // {value: 2, done: false}
conosle.log(g.next()); // {value: 3, done: true}

for (let n of generator()) {
  console.log(n);
}

非同期処理との組み合わせ

// 非同期処理
asyncflow(function * () {
  var items = yield getUrl('/items');
  var id = items[0].id;
  var item = yield.getUrl('/items/', + id);
  console.log(item);
});

function asyncflow(generator){
  var g = generator();
  var next = value => {
    var result = g.next(value);
    if (!result.done) {
      promise = result.value;
      promise.then(value => {
        next(value);
      });
    }
  };
  next();
}

import/export

ES2015 では Webpack などのライブラリを使わなくても AMD や CommonJS の記法を扱うことができる

エクスポート

default export

let foo = "foo!";

export default foo;

class Baz {
  constructor() {
    console.log('Baz!');
  }
}

export default Baz;

インポート

import from

import foo from './foo';
import Baz from './baz';

as

名前を変更できる

import {foo as bar} from './foo';

*

全てをインポートできる

import * as util from 'math/addition';

デフォルトのオブジェクトから、どの機能をインポートするか選択する

import React, { Component, PropTypes } from 'react';

Boostnote はじめた

Boostnote はじめた

これを見たので

GitHubリポジトリで8000スター獲得、人気OSS「Boostnote」オープンソース化の軌跡

所感

Evernote -> Backlog とエンジニアリングまとめを書いてきたが、スニペットが一番使いやすい 。 マークダウンで書けて、すぐプレビューを見れる。カスタム CSS を付けれるのが嬉しい。 Backlog 記法だとそこでしか使えないし今後マークダウンで書いておくことではてなブログ使いまわせる応用がきくと思って乗り換えてみた。 ローカル保存だから動作も早いし、Dropbox の共有フォルダにデータ入れておけば擬似的に端末間で同期もとれる。 UI もいい感じでコーディングが楽しくなる。最初は VS Code でマークダウン書けばよくねって思ったけど、ファイル管理やタグ付けしてくれるので圧倒的に便利。

リンク

Boostnote

Homestead で複数の新規プロジェクトを作ったとき、同名のマシンイメージがあるせいで vagrant up ができない場合

Homestead で複数の新規プロジェクトを作ったとき、同名のマシンイメージがあるせいで vagrant up ができない場合

Mac 環境から vagrant up すると以下のエラーが出た場合の対処法

A VirtualBox machine with the name 'homestead-7' already exists.
Please use another name or delete the machine with the existing
name, and try again.
  1. vagrant up により出来上がってしまったマシンイメージを GUIVirtualBox.app から削除する
  2. Homestead/scripts/homestead.rb ファイルを開き、「homestead-7」となっている箇所を grep して全てリネームする (ここで名前が被っているためエラーが出ている)
  3. vagrant up する

Node.js でサーバ起動したとき、Nginx を使って URL のポート番号を消す

Node.js でサーバ起動したとき、Nginx を使ってURL のポート番号を消す

リバースプロキシ

結論から書くと最初からポート 80 番を指定して使っておけば、URL:8080 みたいなみっともないポート番号で表示しなくていい。
なんだけども、Node.js でそれをやるとセキュリティ的によくないらしい。なので Nginx で HTTP サーバをポート 80 番で立てておいて、 そこで受け取ったリクエストを Node.js サーバに渡すのがセオリーらしい。 これをリバースプロキシという。

/etc/nginx/nginx.conf

下記を修正する。

server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    # サーバー名を記載
    server_name  randomchord.work;
    root         /usr/share/nginx/html;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
        # ポート80 のまま下記の URL にアクセスする
        proxy_pass http://www.randomchord.work:8080/;
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}

ランダムコード

今回の仕組みでこんなサービス作ってます。よろしくです。

素のNode.jsでCSSやJSなどの静的ファイルが読み込めない

素のNode.jsでCSSやJSなどの静的ファイルが読み込めない

Node.js でサーバーを立ち上げるとき、Apache などと違ってドキュメントルートから静的ファイルを読み込むってことを自動でやってくれない。 サーバーにリクエストされた静的ファイルのパスから拡張子を判定してレスポンスを返してあげないといけない。

server.on("request", function (req, res) {
  // リクエストされた拡張子をまず判定する
  chkExt(req, res, function () {
    switch (req.url) {
      case "/":
        // なにかしらの処理
        break
      default:
        // なにかしらの処理
        break;
    }
  });
});

var chkExt = function (req, res, callback) {
  var url = req.url;
  var tmp = url.split('.');
  var ext = tmp[tmp.length - 1];
  var path = '.' + url;
  switch (ext) {
    case 'js':
      fs.readFile(path, function (err, data) {
        res.writeHead(200, {
          "Content-Type": "text/javascript"
        });
        res.end(data, 'utf-8');
      });
      break;
    case 'css':
      fs.readFile(path, function (err, data) {
        res.writeHead(200, {
          "Content-Type": "text/css"
        });
        res.end(data, 'utf-8');
      });
      break;
    default:
      callback();
  }
}

意外と使い勝手がいいソース転がってなかったので書いてみた。

Fire TV Stick × Google Home

Fire TV Stick × Google Home

経緯

最近 Netflix よく見るので今更ながら Fire TV Stick を買った

bluetooth スピーカーとしての Google Home

echo ではなく Google Home だけれども
テレビとかパソコンのスピーカーで聞くよりはよっぽど音がいいので
Fire TV Stick から繋げてみた
例えばドキュメンタリー動画とかだと音がちっちゃかったりするけど
スピーカーだと割と鮮明に聞き取れた
Spotify アプリから音楽流してもいい感じ

Webview

リモコンの精度は結構よくなってきているとはいえ
HTMLでブラウジングしているアプリとか文字入力はまだまだきつい
Youtubeがまさにこれでストレスフル
だから iPhone iPad の動画をミラーリングしようと思ったのだけど...

ミラーリング問題

300円くらいの一番 DL されてる Airplay 専用アプリ airplay and upnp とかいうのを
Fire TV Stick に入れたみたんだけど何十回に1回とかしか認識しない
認識したときはちゃんとスマホの音が Google Home から出ていて感心したんだけど
そのあとがうんともすんとも
ソフトフェアアップデートで改善されるのを待つばかり

ブックマーク問題

firefox などのブラウザが入っているが出来が非常に悪い
画面幅は見切れているし、アカウントでブックマークの紐付けもできないので
パソコンのお気に入り動画を見る、みたいなことは基本的にできない
まあそういう用途で設計していないんだろうけど

総評

5000円くらいなので買いではある
例えば新日本プロレスワールドとかWWEネットワークに加入していた自分にとって
専用アプリが用意されていたし、いつもより大きい画面で見れるは爽快
普段みないテレビがこのような形で利用できたのはよかった
ネイティブアプリの出来はいいものが多いし
オンデマンドの動画はほとんどアプリで見れるんじゃないかな
ただそれ以外の痒いところに手がとどく使い方はできないって感じかな

vue.jsでブログジェネレータを作ってみた

vue.jsでブログジェネレータを作ってみた

つくったもの

わくわくブログジェネレーター github.com

経緯

LIG的なセリフ形式のブログを始めてたけどコーディングがめんどくさい!

<div class="talk-wrap">
    <div class="left-icon" style="background-image: url('../img/talk_img/00.png');"></div>
    <div class="talk-left">
        <p>こんなん毎回コピペして書き直してられっか</p>
    </div>
</div>

開発環境

  • Vue.js
  • Bootstrap4

感想

React よりもとっつきやすい!
双方向データバインディングならでは、ってことがずっとしたかったので
今回はとりあえずリアルタイムな値表示と簡単なバリデーションをかけてみました
VueXにも挑戦したいけどReduxの件があるからなあ...
もうちょっとvue.jsで遊ぶかもしれない
あ、そうそう何気にGitHubもはじめてます、た

Magic Keyboard (US) → HHKB Professional BT (US 無刻印) にした話。あとMagic Trackpad (スペースグレイ)も

Magic Keyboard (US) → HHKB Professional BT (US 無刻印) にした話。あとMagic Trackpad (スペースグレイ)も

f:id:loney1986:20180415204407j:plain

経緯

副業のあぶく銭が入った。ずっとほしかった

所感

HHKB BT(US 無刻印)

  • 純正のMagic Keyboardと比べると遅延あり。でも気にするほどでもないレベル
  • ついタイプでスリープを解こうとするがキーボードも30分経過でスリープしてるから無理
  • スリープしない設定もできるが電池もったいないので、自分でスリープ解くことを選んだ
  • Controlキーの位置が慣れない。矢印がない。ということは慣れないControlキーの位置に慣れる必要がある
  • 無駄なキーを排除しているので物理的に遠かったキーは押しやすくなっている
  • セブンのATMみたいなスコスコ打鍵感。触っていて気持ちいい
  • 打鍵音がうるさいらしい、でもそれはみんながAppleのヘコヘコキーボードを使ってるからそう感じるだけかと
  • 指の負担が軽減される訳ではなさそう
  • 当然のことながら今すぐタイピングが早くなる魔法の道具ではなかった
  • 単純な英数字の入力だけなら初日のスピードは変わらなかった。問題は入力切替とかショートカット
  • しかし配列やコマンドをマッスルメモリーに叩き込んでしまえば早くなりそうな予感がある
  • というか無刻印にした以上そうならざるを得ない
  • すべての構造が最適化されているので名前どおり入力が楽しくなりそう (マゾ気質)

Magic Trackpad

  • ワイヤレス製品全てにいえるけどやはり無線で好きな場所に置けて、自身が楽な姿勢を保てるのはストレスフリー
  • Macbookについてるやつより大きい
  • 気持ちはiMac proユーザ
  • Magic Mouseから乗り換えたような形だが、できるアクション数はやはり多いし増えてる
  • Magic Mouseのカーソルの早さより上げられてるっぽいので必要な動作が減る。省エネ
  • 指の関節はやっぱり疲れる
  • キーボードで極力なんでも操作したいモードだから必要なときにだけアシストしてもらう感じ。かといって存在が邪魔にならない
  • まだできることがありそうけどHHKBのせいで構ってあげられていない
  • ごめんね

今回の出費は5万円
HHKBの鞄とカラーキートップも付けたらこんなにいってしまった...
まぁでも一生使えるし、商売道具だしと考えれば

追記

純正マウスの速度あげれたやん。速度は5.5くらいがいい感じ

anote.work

EC2上のRDS (MySQL) をVS Codeで使えるようにする話

EC2上のRDS (MySQL) をVS Codeで使えるようにする話

契機

「え?エディタで DB 見れるようにしてないの?」

つまずいた

VS Code で MySQLプラグインをつっこんで追加ボタン
必要情報を入力

・・・タイムアウト発生

そもそも

前提として EC2 で動かすのに、EC2 のログインが求められていないゾ
MySQL Workbench とか コマンドラインのときは両方でログインをしなければいけなかったのに

あ、なるほど

AWS のセキュリティグループで「MySQL (3306) 」が「0.0.0.0/0」になっていない
ここで解放してあげて、公開鍵は EC2 の pem ファイルを指定してあげれば
直接 EC2 ログインしなくとも無事表示されました

参考

a1-style.net

その他

rmate を使って、VS Code からリモート編集できるようにしたかったので
こちらのポートも追加しました
qiita.com

毎日その日のタスクを自動通知する Slack bot 作った話

毎日その日のタスクを自動通知する Slack bot 作った話

経緯

つまり

スプレッドシート
1. 工数管理 (自動計算)
2. 工数管理の情報を元に1ヶ月のスケジュールを組む
3. Slack で毎日その日のタスク通知してくれたら便利やん!
と思った (月並)

スプレッドシート作成

  • 工数管理シート
    タスクの工数を自動計算してくれるシート f:id:loney1986:20180408114309p:plain

  • スケジュールシート
    1ヶ月のタスクを登録しておくシート f:id:loney1986:20180408114142p:plain

  • Slack シート
    f:id:loney1986:20180408114331p:plain Slack で通知して欲しい情報はこのシートで全て管理している
    TODAY() で日付オブジェクトを作り、
    MATCH() でスケジュールシートの日付とマッチした行番号取得
    その行番号に欲しい情報が全てあるので、列名と組み合わせて文字列のセル番号を作成
    indirect() で文字列セル番号をオブジェクト化して、値を参照できるようにしている

GoogleAppScript (GAS)

ただの JavaScript だった

function myFunction() {
  // spread sheet 取得
  var sheet    = SpreadsheetApp.openById('13RzmCmRRsYc4N2MU9xwJoRVhDQLjqNwkrhj5dc8YUVU');
  
  // 拾うシートの名前
  var sheetName = 'slack';
  
  // 日付
  var today = sheet.getSheetByName(sheetName).getRange(1,1).getValue();
  
  // 曜日
  var week = sheet.getSheetByName(sheetName).getRange(1,2).getValue();
  
  // タスク名
  var task = sheet.getSheetByName(sheetName).getRange(1,3).getValue();
  
  // 大目標
  var big = sheet.getSheetByName(sheetName).getRange(1,4).getValue();
  
  // 中目標
  var medium = sheet.getSheetByName(sheetName).getRange(1,5).getValue();
  
  // 小目標
  var small = sheet.getSheetByName(sheetName).getRange(1,6).getValue();
  
  // タスク進捗率
  var percent = sheet.getSheetByName(sheetName).getRange(1,7).getValue() * 100;
  

  var sentence = 
    "-- *きょうのいけだの衝動* --\n" +
    "*" + task + "* [ *" + percent + " %* ] " + "\n" +
    "\n" + 
    ":yavai: 大目標 `" + big + "` \n" +
    "\n" + 
    ":yavai: 中目標 `" + medium + "` \n" +
    "\n" + 
    ":yavai: 小目標 `" + small + "` \n" +
    "https://drive.google.com/open?id=13RzmCmRRsYc4N2MU9xwJoRVhDQLjqNwkrhj5dc8YUVU";
  
  var payload  = {
    'text'      : sentence,
    'channel'   : 'stand_up'  ,  // 投稿するチャンネル
  };
  
  var options = {
    'method'      : 'post'                 ,
    'contentType' : 'application/json'     ,
    'payload'     : JSON.stringify(payload),
  };
  
  var url = '(Slack incoming WebhookでコピーしたURL)';
  
  UrlFetchApp.fetch(url, options);
}

完成

まりこ様 bot が決まった時間に通知してくれるようになりました f:id:loney1986:20180408115201p:plain

参考

www.tam-tam.co.jp

tech.camph.net

www.minemura-coffee.com


Slack 設定画面が変わり続けているので、色々と昔と違うところがありました
今回使ったトークンの種類は Webhooks です
共有リンクはオンにしておかないと届かないみたいです
覚えたばかりの工数でいうと1人日かかりました

HTTPSの導入と挫折

カイカフカイカの HTTP 対応を行った。

使ったのは Let's Encrypt

無料で有名なとこっすね。

素の HTTP だと Google Chrome で今後警告が出てしまうということで、勉強を兼ねた導入。

導入自体は簡単だったんだけど、ランダムコードは Node.js からインスタンスを立ち上げていて

そのインスタンスを切らずにドメイン全体をSSL化した影響からか

Mongo.db が動かなくなってしまった。ふつうの mongo コマンドさえ。

でてきたエラーは以前と同じ。

そのときの方法だと直らなかったので、

MongoDB アンスコ、再インストールすればすぐ治った。

lockファイルの削除やらerrオブジェクト・configの確認まで色々やったんだけどね...

結局これが一番早かったという。

そういうわけでランダムコードのHTTPS対応だけはもう少し後になりそう。

 

 

 

TotalSpaces2 買った

UdemyでReactの講座やってる人のTwitterみたらおすすめされてたので購入 (約1600円)
設定は下記参照

qiita.com


画面管理に使ってた頭のリソースが解放された気がする
あと、画面の切り替えがめっちゃサクサクになった