プログラミング生放送勉強会第25回@品川に参加しました。
Windows ストア アプリケーションのUIデザイン
- UX
- ユーザビリティテスト
- マニュアルは読まれない前提でUIを作る
Modern Style
- Metroと呼ばれていたもの
- 10フィート離れたところからリモコンで操作出来るように
- 日本の地下鉄は複雑だけど、路線図を見れば、なんとなくわかる→Metro UI
Application Design
- タブレットのデザインは難しい
→広い、統一できない、まとまらない - コンテンツが最優先
そぎ落とす
- Crome(余計な装飾・今使わないメニュー)は要らない
- 左上は一番重要
→コンテンツを置くべき - RSSリーダーに、3つもペインは必要ない。人間は一度にそんなに情報を処理できない。
- 重複なアイコン→共通メニュー(アプリバー)
- ほんとうに、今、これが必要なのかを考えて作る
- デベロッパーはデザイナーの下僕です。
構造とリズム
- タイポグラフィ
- 非デザイナーがなんとなく作って、なんとなくかっこ悪いのはルールがないから
- フォントも4つに絞る(9pt, 11pt, 20pt, 42pt)
- 文字サイズを大きくすると、細いフォントを利用する
- グリッド
- 1unit = 20px x 20px
- 1sub unit = 5px x 5px
軽快に、滑らかに
- ビジュアルなフィードバック
- スプラッシュスクリーンの本当の意味は、起動にかかる時間をごまかすため
- 5mm なら、30回に1回ぐらいタップミスする
- 7mm なら、100回に1回ぐらいタップミスする(だいたい大丈夫)
デザインガイドラインをぜひ見てください(MSDNのUXパターン)
Leap Motion ではじめるNUIプログラミング
NUI概要
- Project Natal(のちのKINECT)
- 3D深度センサー・RGBカメラ・マルチアレイマイク
Leap Motion概要
- 様々な言語で開発可能
- デモアプリがかっこいい
C#によるLeap Motionプログラミング
- センサーの視界領域にある手や指を追跡
- Controller, Listener などのクラスが用意されている
- PUSH形式とPULL形式のデータ取得が可能
- ListenerのOnFrameでFrameを取得して操作する
- Gestureは4種類
- onFrameはすごい勢いで呼び出される(秒間数十?)
- InteractionBoxクラス(箱状の領域を設ける)
ソフトウェアアーキテクチャの求め方
結局何を決めなければいけないのか?
- アーキテクチャという言葉の定義に「万人の合意」は存在しない
- 複雑さへの対処
- 整理・細分化を行う→「関心事の分離」
- 開発や運用が容易な大きさの集合に分解する
- モジュール化・カプセル化
再利用可能は必須ではない
設計パターンを用いた分離
- 設計パターンといわれるものは、本質をつかみづらい
用語の誤認と誤った情報が配信されているため - 関心事を分離する視点そのものが、いわゆる設計パターン
切った結果ではない
→サンプルコードから読み取ることは不可能 - 設計パターン→設計視点
実際の分離で使用する視点の例
- Presentation Domain Separation(PDS)
- 分離したいのは、プレゼンテーション部分は他のコードと別の知識・制約がかかるから
- 次の入力フォーカスをどこに置くべきかは、Domain側に書くべき
- 資料:「GUIアーキテクチャの基礎からMVVMパターンへ」
PDSとは、アプリケーション全体から「PresentationPlatform関連」を分離する「視点」
Domain Logic Pattern
- アプリケーションの状態の持ち方の特性で大きく分かれる
- TransactionScript or Domain Model
- 資料:「Modelの中身 - ドメインロジックパターン」
- TransactionScriptが有用な場面ではDRY原則は原則ではなくなる
DomainModelで継承してると、仕様変更で継承関係が変わってしまうと大変になる
大きな食べ物を順々に切り分けていく間隔
前のステップでの切り方によって、次のステップの切り方は変わってくる
まとめ
- すべては「関心ごとの分離」に通ず
- 「設計パターン」って言葉よくないよ!
- 大体いつも使う知見:PDS(MVC系の裏), Domain Logic Pattern
- なぜそうしたいのか?なぜこれが必要になったのか?から考え直す
- どこにも載ってない情報は自分で考えるしかない
Visual C++ は C++10.8 ←イマココ
delegating constructor
uniformed initialization
- "()"ではなく、"{}"でコンストラクタを呼び出す
cplx c0(); では、関数宣言になってしまう
initializer_list
- initializer_list という型の定義
追加・挿入・変更できないコンテナ
initializer_list<int li { 1, 2, 3 };
explicit conversion operator
- 暗黙の変換を抑止する "explicit"がないと、加算出来たりする
LT
@ZuQ9Nn 自作アプリの宣伝
- 虹人間カメラ - RainbowMainCamera
- あざとい感じのアプリ名
- なんの成果も得られませんでした
- 初日1桁DL
残念な原因 - アプリの説明がわかりにくい - 宣伝を全くしなかった - 露出が少なすぎるために、存在していないのと同じ
- 現在、App Storeのランキングはお金で買える
→個人が趣味で作って上位になるのは大変難しい
@@ww24 FlashAir x Node.js
@_kz6 Javaを勉強してわかったこと
@azyobuzin イカすJava Xtendの話
- Java嫌い
- 一般的な高校生には理解できない
- Java1.5相当に変換される
- Eclipseのプラグイン
- ラムダ式
- 拡張メソッド
- プロパティ
- null 処理
- No Statements
- 型推論
- defで戻り値の型を書かなくて良い
- ドキュメントに書いてあっても出来ないこともある
- それでもJavaよりまし
@mikan_x コミックマーケットでの携帯電話のお話
- いつも電波悪いよね
- C84では改善された
- 以前まではau, docomoが厳しかった
- 201THを使え(衛星電話高い)
- emobileはユーザが少ないから最強
- 電波が無いなら、迷子にならないで
- 将来的にwebカタログが使えるかも
@shinoblogavi お絵かきツールとしての Blend と Power Point
- パスで描く
- 部品管理とグループ化は大事
- 図形の結合
- トリミング・図形貼り付け・半透明化
- パワポまじ凄い
@daruyanagi プロ生ちゃんの声をアプリに組み込もう
- Expressでも使える
感想
- MSはUI/UXに頑張ってる
- Leap Motionすごい。欲しい。
- ソフトウェアアーキテクチャを考えるためには、視点を学ぶ必要がある
- gloops はアーキテクチャをしっかり考えて作ってるっぽい
- C++、言語としては残念
- FlashAirすごい
- PowerPointまじすごい。絵を描ける
- プロ生ちゃんって、結局なんだったのだろう(ぇ
第一回 納涼もんご祭りに参加しました
参加したセッション
話を聞いた・パンフ貰ったブース
- 「さくらのクラウド」デモ
- ソーラーパネル、どこへ置く?
- もんごの薄い本
- CodeIQ
- co-meetingのご紹介
MongoDBについての感想
- アプリケーションを作るのに便利な機能が備わっている
- 特に、地理空間インデックスはハマれば強そう
- レプリケーション・シャーディングが簡単そう
- スキーマレス
- migrationが不要なのはいいけど、管理が難しそう
- SQLライクな動的クエリが便利そう
- ただし、性能はどのぐらい?オンラインの取得に使えるレベル?
- トランザクションが無いので、割り切りが必要
- ミッションクリティカルな分野では使えない
- 書き込み性能より読み込み性能を重視している
- 普通に運用しようと思ったら、3台必要なのかな。。。
- WEBサーバにセカンダリ・プライマリサーバ・hiddenなセカンダリサーバ ってのが事実上の最小構成?
あれ、そういえば、参加受付ってどこにあったの・・・?
ふつうのエンジニアの情報収集法
会社の後輩に、どーやってそういう(エンジニア的な)情報を集めてるのか聞かれたので、
自分の中での整理のためにも書いてみる。
下準備
Twitterで、それ系の発言をしている人をフォローする。
→そこで発言している人たちをフォローしていく
http://tagamidaiki.com/tech-twitter10/ とか出てくるので、気になったらフォロー。
- twitterがおすすめユーザを表示してくれる
https://twitter.com/who_to_follow/suggestions
後述するサービスでリンクを集めてくれるため、URLを含んでつぶやいている人多めの方がよいと思います。
数百人レベルでフォローしちゃえばいいと思います。
ただ、タイムラインは読めたものではなくなる(流速的に)と思います。
はてなブックマーク - マイホットエントリー
http://b.hatena.ne.jp/
http://bookmark.hatenastaff.com/entry/2013/05/08/131308
はてなのIDと、Twitter・Facebookを連携させる。
朝9時(通勤時間前)にメールを送信するようにする。
→電車の中とか、会社着いてから読む
→一通り読んだらメールを削除(未読・既読管理)
→あとで利用できそうな内容だったら、はてブでブックマークしておく(Twitter連携もしておくと、それ系のフォロワーが増えるかも)
物足りなかったら、「テクノロジー」タブを眺める。
Gunosy
http://gunosy.com/
Facebook・Twitter・はてなのアカウントと連携させる。
「日々のまとめメールを配信する」にはチェックを入れておく。
→一通り読んだらメールを削除(未読・既読管理)
リンクを踏んだものを学習してくれるようなので、気になったものだけリンクを踏む。
昼休みに読む。
http://getpocket.com/
はてな・Gunosyで気になったけど、そのとき時間がなくて読めないものを突っ込んでおく。
Read It Now(https://play.google.com/store/apps/details?id=hm.orz.chaos114.android.readitnow&hl=ja)にて、
state = unread
sort = oldest
のウィジェットを作って、読み終わったら delete or archive しておく。
(ウィジェットに表示される数字を0に保つ気概で)
RSS
上記で様々なサイトを見ていく中で、自分の興味ある分野の記事を多数書いている人がいれば、RSSを配信していないか調べる。
配信している場合、RSSリーダーに突っ込み、新着を読む。
自分の場合は、RocketSS(http://rsspocket.appspot.com/ )にRSSのURLを突っ込んで、自動的にPocketに保存されるようにしている。
その他(暇な時)
Qiita
Forkwell
電子書籍
一つの言語・フレームワークなどの一通りの情報を抑えたかったら、本を読むのは手っ取り早いと思う。
電子書籍なら、タブレット(AQUOS PAD)一台で、何冊でも持ち歩けるので便利。
- 達人出版会 http://tatsu-zine.com/
- O'Reilly http://www.oreilly.co.jp/ebook/
- オーム社 http://estore.ohmsha.co.jp/titles
- 技術評論社 https://gihyo.jp/dp
(Advent Calendar以外にめぼしいものは無いかも。。。)
※実話ですが、ステマでもありますw
rbenvをインストール
環境:Mac OS X 10.8.4
rbenvのインストール
基本、下記の通り。
https://github.com/sstephenson/rbenv
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
その後、書いてある通り、ruby-buildを入れる。
https://github.com/sstephenson/ruby-build
ちなみに、入ってないと、rbenv installってやっても
rbenv: no such command `install'
てエラーが出る。
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
これで、下記のコマンドが実行できる
rbenv install -l
2.0.0-p247 ってのがあったので、それをインストールする。
rbenv install 2.0.0-p247 rbenv rehash rbenv global 2.0.0-p247
下記も参考にしました。
http://rochefort.hatenablog.com/entry/20121015/p1
http://qiita.com/sifue/items/b7d252b18ebbae636fa9
RocketSSにサービス名を変更しました
昨日、一応のリリースをした「Rss to Pocket」ですが、さっそくサービス名を変更しました。
新しくは「RocketSS」になります。
(ドメインは面倒なので変更しません。。。)
http://rsspocket.appspot.com/
会社で話してたら、そのまま過ぎるというdisりと、RSS+Pocketでろけっとでいいんじゃない?という話が出たので、ほぼ採用。
Rocketだと検索に引っかかりづらそうだったので、余った"SS"を後ろに付けてみて、RocketSSに落ち着きました。
サービス名は、さすがにもう変えないと思います。多分。
使い方について、Facebookで聞かれたので、
http://rsspocket.appspot.com/home
に手順を書いてみました。
時間があったら、スクリーンショットとか追加しようと思います。
で、すっかり忘れていた、Read It Nowへのリンクもついでに追加しました。
これでダウンロード数が伸びるといいなー。。。
Rss to PocketというWEBサービスを公開しました
Rss to Pocket
http://rsspocket.appspot.com/
出来ること
- RSSを登録しておくと、Pocketに自動的に記事が追加されます
- RSS毎に「タグ」を付けられるので、Pocket内で整理しやすい
- Google Readerからエクスポートしたファイルを読み込める
雑記
本当は、Google Readerが停止する前に公開したかったんですが、気力が足りずに遅れてしまいました。
現状はタグの編集など、必須と言っていいぐらい機能すら実装出来てないので、随時更新していきます。
NeoBundleを有効にすると、シンタックスハイライトが無効になる
環境
Mac OS X 10.8.4
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Jun 20 2012 13:16:02)
最初は、下記のように書いていた。
syntax on set nocompatible if has('vim_starting') set runtimepath+=~/.vim/bundle/neobundle.vim/ endif call neobundle#rc(expand('~/.vim/bundle/'))
で、最終行をコメントアウトすると、シンタックスハイライトが有効になるのに、
最終行を有効にすると、色がつかない。
結論:syntax on を最後に持ってくる
下記のように変更したら、色がついた。
set nocompatible if has('vim_starting') set runtimepath+=~/.vim/bundle/neobundle.vim/ endif call neobundle#rc(expand('~/.vim/bundle/')) syntax on
Pocket APIのにて、タグのAND検索
AND検索はできる模様。
・やり方
tagパラメータを複数つける
https://getpocket.com/v3/get?consumer_key=XXXX&access_token=YYYY&tag=hoge&tag=fuga
上記により、"hoge"タグと、"fuga"タグの両方が設定された記事だけ取得できる。
OR検索のやり方は不明。
主キーを任意のカラムに変更する
slim3のデータクラスは、Keyクラスでなければならないようです。
https://sites.google.com/site/slim3documentja/documents/slim3-datastore/defining-data-classes
でも、ユーザの情報を格納するデータクラスはemailアドレスにしたいですし、emailアドレスで検索したいです。
いろいろやり方はあるようです。
http://d.hatena.ne.jp/higayasuo/20091111/1257905482
http://www.tdtsh.com/blog/archives/759
が、今回はユーザに紐づく情報(同一タイミングで別の更新が入ることを考慮しない)こともあり、てきとーに組んでみました。
package hm.orz.chaos114.gae.rsspocket.dao; import hm.orz.chaos114.gae.rsspocket.model.UserInfo; import java.util.List; import java.util.concurrent.Future; import org.slim3.datastore.DaoBase; import org.slim3.datastore.Datastore; import org.slim3.datastore.EntityNotFoundRuntimeException; import com.google.appengine.api.datastore.Key; import com.google.appengine.api.users.User; public class UserInfoDao extends DaoBase<UserInfo>{ @Override public Key put(final UserInfo model) { setKeyIfNull(model); return super.put(model); } @Override public List<Key> put(final List<UserInfo> models) { // 利用しないため未実装 throw new UnsupportedOperationException("未実装"); } @Override public Future<Key> putAsync(final UserInfo model) { setKeyIfNull(model); return super.putAsync(model); } @Override public Future<List<Key>> putAsync(final List<UserInfo> models) { // 利用しないため未実装 throw new UnsupportedOperationException("未実装"); } /** * Userが一致するUserInfoオブジェクトを取得する。 * * @param user ユーザ情報 * @return UserInfoオブジェクト */ public UserInfo getByUser(final User user) { final Key key = createKey(user); try { return get(key); } catch (final EntityNotFoundRuntimeException e) { return null; } } /** * Keyが設定されていない場合は、設定されているUserからKeyを生成し、設定する。 * * @param userInfo ユーザ情報モデル */ private void setKeyIfNull(final UserInfo userInfo) { if (userInfo.getKey() == null) { userInfo.setKey(createKey(userInfo.getUser())); } } private Key createKey(final User user) { return Datastore.createKey(UserInfo.class, user.getEmail()); } }
put系のメソッドをオーバーライドし、Userのemailより作成したKeyを設定しています。
また、getByUserにて、指定されたUserオブジェクトのemailよりKeyを作成し、取得しています。
(put系のListを引数にとるメソッドを利用する予定が無かったので、実行時に例外となるようにしてあります。使うことがあれば、実装する予定です。)
現在開発中のものより抜粋(https://github.com/noboru-i/rsspocket)
Virtual BoxでJenkinsを動かす
前提:
Vagrant: 1.1.2 (公式サイトからダウンロード)
Chef: 11.4.0 (rubygemでインストール)
knife-solo: 0.3.0 (githubからcloneしてインストール)
Opscode Communityに登録済み・鍵を設定済み
※コンソールの出力結果を見ながら、思い出しながら書いているので、抜けがある可能性あり
※大問題:下記を実行後に、"vagrant halt"→"vagrant up"しても、Jenkinsにアクセス出来ない。
chefで実行されたが、起動時に実行していないことがある?
適当なフォルダでVagrant公式にあるスクリプトを実行
mkdir vm cd vm vagrant box add base http://files.vagrantup.com/lucid32.box vagrant init
Vagrantファイルを少し修正し下記のようにする。(コメントアウト以外の箇所を抜粋)
Vagrant.configure("2") do |config| config.vm.box = "base" config.vm.network :private_network, ip: "192.168.50.11" config.vm.provider :virtualbox do |vb| vb.customize ["modifyvm", :id, "--memory", "1024"] end end
やっていることは、
・先ほどダウンロードしたubuntu(baseとラベリング)を利用する
・固定IPを設定
・メモリ使用量を1024MByteに設定
VMを起動する。また、sshで入れるようにしておく(ここでは"vm"という名前を設定)
vagrant up vagrant ssh-config --host vm >> ~/.ssh/config
Chefリポジトリを作成する。
knife solo init chef-repo cd chef-repo git init git add . git commit
vm上にchefを準備する。
knife solo prepare vm
nodes/vm.json が作成されるので、gitにcommitしておく。
jenkinsのcookbookを追加して、"run_list"に"jenkins"を追加し、実行する。(途中gitのcommitが複数回走るが、とりあえず全部":wq"でそのまま続行)
knife cookbook site vendor jenkins vim nodes/vm.json knife solo cook vm
エラーになる。
Cookbook apt not found. If you're loading apt from another cookbook, make sure you configure the dependency in your metadata
include_recipe "apt" ってところでエラーになってるっぽいので、"apt"を落としてくる。
knife cookbook site vendor apt
そのままやると、vm.jsonを変更しているので
You have uncommitted changes to your cookbook repo
といわれる。一旦変更を破棄して、再度実行する。(commit or stashしてもよい)
knife cookbook site vendor apt
無事、"apt"が取り込めたので、再度cook。
knife solo cook vm
再度エラー。
Cannot find a resource for apt_repository on ubuntu version 10.04
今度は、"apt_repository"というResourceが見つからないと言っている。
とりあえず、エラーメッセージでググり、 https://github.com/mdxp/nodejs-cookbook/issues/16 を見つける。
コミットログを見ると、"metadata.rb"に「depends "apt"」と追記しているみたい。やってみる。
cookbooks/jenkins/metadata.rb に1行追加
--- a/cookbooks/jenkins/metadata.rb +++ b/cookbooks/jenkins/metadata.rb @@ -5,5 +5,7 @@ description "Installs and configures Jenkins CI server & slaves" long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version "0.6.3" +depends "apt" + %w(runit java).each { |cb| depends cb } %w(iptables yum apt).each { |cb| recommends cb }
再度実行。
knife solo cook vm
やっと成功。
最初に決めたIPで8080ポートにアクセス。
http://192.168.50.11:8080/
Jenkinsおじさんが見えれば完了。
Vagrant, chef solo, knife soloなどを利用して、Jenkinsサーバが作れました。
普通に構築したことが無いので、比較は出来ないのですが、思ったより簡単に出来ました。(罠はありましたが)
dependsを記述する場所が間違っている気がしますが、ホントはどこに書くものなんでしょう。。。
あと、最初に書いた大問題(再起動後に見えない)はどうしたらいいやら。。。