2010年6月22日火曜日

iPhoneのCode Signingエラーを何とかする

三森です。今日はさっき遭遇したiPhone開発のトラブル・シューティングについて書きます。
他の人にもらったiPhoneのプロジェクトファイルを自分の実機にインストールするとき

Code Signing Identity 'Erica Sadun' does not match any valid, non-expired, code-signing certificate in your keychain.

のようなエラーが出ることがあります。ちなみに上のエラーは、iPhoneハックの女王エリカ様のサンプルコードをコンパイルしようとした時のものです。
このエラー対策をググると、XCodeのメニューでコード署名IDを自分のものに直せばいいのだという情報を見つけました。しかし自分の場合はそこを変えただけではうまくいかなかったので、直接プロジェクトファイルを見てみました。
プロジェクトファイルは拡張子.xcodeprojですが、これは実はディレクトリーになっていて、その中のproject.pbxprojというファイルにビルド設定などが含まれているようです。右クリックして「パッケージの中身を表示」で以下のように開けます。



project.pbxprojはテキストエディットなどで見ます。すると以下のような行があります。


"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Erica Sadun";

このCODE_SIGN_IDENTITYというところがエラーの原因でした。自分の実機に入れるときはここを

"CODE_SIGN_IDENTITY" = "iPhone Developer";

に変更すれば動くようになります。本来はメニューから変えられるはずなのでXCodeのバグかもしれません。

ところで、エリカ様のサンプル・プロジェクトは実に沢山あるので、いちいち直していくのは面倒です。なのでバッチを書きました。別にエリカ様のサンプルでなくても使えます。

USAGE:

$ sh modify_code_sign.sh <ディレクトリー>

として使うと、<ディレクトリー>以下全てのproject.pbxprojファイルのCODE_SIGN_IDENTITYを書き換えます。元ファイルに上書きするので一応使用前にバックアップしてください。もし壊れても責任は負えません:-)

以下、ソースです。

#!/bin/sh
#This file is modify_code_sign.sh

SPACE_ESCAPE="\*SPACE\*" #ファイル名の一時変更(for対策)
REPLACE=CODE_SIGN_IDENTITY
FILES=$(find $1 -name project.pbxproj | sed "s/ /$SPACE_ESCAPE/g")
for FILE in $FILES; do
FILE=$(echo "$FILE" | sed "s/$SPACE_ESCAPE/ /g")
echo $FILE
CONTENT=$(cat "$FILE" | awk 'BEGIN {c=1} /'$REPLACE'/ {if (c==1){c=0; print "CODE_SIGN_IDENTITY = \"iPhone Developer\";";}} !/'$REPLACE'/ {print $0}')
echo "$CONTENT" > ${FILE}
done

2010年6月15日火曜日

GAEとjavascriptでjsonをやり取り

2週間ぶりの三森です。
今日はjsonでのデータやり取りについてちょこっと書きたいと思います。
環境は、Google App Engine(python)とjQueryの使用を想定して書きます。

json形式はjavascriptのオブジェクトをほぼそのまま表現でき、かつコンパクトなので、
クライアントからサーバーに何か階層の深いデータを送る時に使うと楽です。
json形式で送るときは、普通POSTメソッドを使うと思います。
jQueryのajaxメソッドでは、dataTypeを"application/json"に設定すれば、
urlエンコードなどをしないで生のjsonを入れて送信できます。
オブジェクトをjsonの文字列にするにはjson2.jsを使うのが簡単です。
JSON.stringifyはエンコード、JSON.parseがデコードです。


var json = JSON.stringify({"a": {"b": {"c": ["d", "Hello json!"]}}}); //objをエンコードする

$.ajax({
async: true,
complete: function(){},
dataType: "application/json",
data: json, //JSON
processData: false,
error: function(XMLHttpRequest, textStatus, errorThrown){
//httpエラーの場合処理
}
success:function(data, dataType){
//成功した場合の処理
alert(JSON.parse(data)["b"]["c"][1]);
}
type: "POST",
url: "http://使っているドメイン/json"
});


GAEの方では組み込みで入っているsimplejsonモジュールを使えます。
pyhtonオブジェクトとjsonとの変換は、デコードがsimplejson.loads(str),
エンコードがsimplejson.dumps(obj)です。

下のコードでは、JsonApiというクラスにurlをルーティングしてそのなかでjsonを読み込み、
responseに返します。うまくいけば"Hello json!"というアラートが出るはずです。


import cgi

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from django.utils import simplejson

class JsonApi(webapp.RequestHandler):
def post(self):
str = self.request.body
try:
loaded = simplejson.loads(str)
self.response.headers['Content-Type'] = "text/plain"
self.response.out.write(simplejson.dumps(loaded["a"]))
except:
self.response.set_status(404); #parse errorなどの場合

def main():
application = webapp.WSGIApplication([('/json', JsonApi)])
run_wsgi_app(application)

if __name__ == "__main__":
main()


以上です。記事にするほどの内容か分かりませんが、ドキュメントを読まないで
勘でやっていると意外に時間がかかってしまったりするので、ここにまとめておきました。

2010年6月11日金曜日

議事録

キクチです。

我々 Sphia メンバーは毎週土曜日に全体会議を実施しています。

しかし自分は今週来週と土曜に本業での仕事があるため、参加することができません。
アメリカにいる長谷も当然参加することができません。

しかし、会議内容は後から追いたいし、不在メンバーへ情報共有もしたい。
ここで議事録が重要になってきます。

今日は議事録についての話をしようと思います。


議事録を書く目的としては、2種類あります。

-----------------------
1. 情報の整理・共有
2. エビデンス
-----------------------

土曜の全体会議は内部会議なので、1 が目的となりますね。
アジェンダ、決定事項、決定経緯、残課題等が誰が見ても見やすくまとめられている必要があります。

会議に出席しなかった人が読んで理解できる書き方が重要だと思います。
途中でプロジェクトに参加したメンバーが後から見て分かるようにとか。

逆に、今の Sphia ではまだありませんが、クライアントとの会議の場合は、2 の議事録となってきます。
ここでの目的はエビデンス(証拠)ですので、後から言った言わないの問題にならないようにするために書きます。

究極のエビデンスとしては、一字一句逃さないテープおこしがありますね。
物凄い労力がかかりますけど。。


議事録書きも簡単にはできない重要なスキルだと思います。
見せ方、事実と意見の違いの整理、構成力等のスキルが必要となります。

今の Sphia の土曜の全体会議では、毎回当番制で議事録をとっていますので、全員でスキルを上げていきたいですね。

2010年6月10日木曜日

ファイナンシャルプランナー

先日、実家に帰ると、FP(ファイナンシャルプランナー)の参考書がありました。

母が「ファイナンシャルプランナーという資格を取ることにした~」と意気揚々と言っていました。

昨年はDSの英語脳?か何かにハマっていた母ですが、
今度はFPの勉強に勤しんでいるようです。
仕事とは全く違う分野の知識を吸収しようとする姿は見習いたいものです。

私も一緒にFPの勉強をしようかな~。

2010年6月4日金曜日

スタートアップとは

こんばんは。キクチです。

今日は企業のスタートアップに関する記事をいくつか紹介したいと思います。
ポジティブな話もネガティブな話もあります。


スモールビジネスを興して成功するための9条件
http://fukui.livedoor.biz/archives/3234527.html

立ち上げた途端にダメになるスタートアップ企業
http://www.seojapan.com/blog/立ち上げた途端にダメになるスタートアップ企業


検証することを忘れずに事業を進めていきたいと思います。

2010年6月2日水曜日

大プレゼン大会

企画部的場です!

早いものでもう水曜日ですね。最近一週間が本当に充実していて、飛ぶように過ぎていきます。


さて、先日キクチがブログに書いたように、土曜日はSphia全員によるプレゼン大会でした!

プレゼンを本気で作って、本気で発表するっていうのが、本当にビジネスコンテスト以来だったので緊張し、緊張を上回るほど楽しかったです。

前日はもちろん、夜が白むまで全員のスカイプが緑色でした(笑)

徹夜明けのハイテンションでした。


やってみて思ったのは

一つのものを作ろうとしている仲間でも、こんなにも考えていることが違うのか

と言う事でした。

コンセプトの解釈、想定する問題、ターゲット。。。

あらゆるものが、その人の”オリジナル”

でした。

非常に有意義な時間で、また、全員が一歩成長したような一日でした。

2010年6月1日火曜日

Wikipediaで言葉の距離を測る

火曜の三森です。僕は一応自分のブログもやっていますが、こんなに毎週続けるのは初めてです。もはや自由研究と化していますが、前回のWikipediaネタの続きをやってみたいと思います。

前回は、適当に選んだ単語のWikipediaのページにあるキーワードリンクを全て拾ってくる事をやってみました。今回はそのアイディアを使って、単語同士がどれぐらい関係しているのかを調べてみました。「友達の友達が6人先まで行くと世界中の人がつながる」というのは有名な話ですが、単語の場合はどうなっているのか?というのは興味深いところです。方法は単純で、スタートの単語とゴールの単語を決め、その間に必要なジャンプの数を数えます。ただし

・スタート、ゴールの単語にあたるWikipediaのページがなければアウト
・ページ・リクエスト回数の上限を越えてもゴールに着かない、またはどこにも行けなくなったらアウト
・「7月15日」、「1600年」のように数字を含むものはキーワードと見なさない(多過ぎるから)

という設定にしてあります。ジャンプの回数はAPIを叩きすぎないようにMAX_COUNTSで決めてあります。
この条件でいかに単語間距離を稼げるか・・・を対戦してみたら面白いかもしれません。
やり方は、ブログの下に貼ったソースコードをwikisurf.pyで保存し、コマンドラインから


$ ./wikisurf.py 単語1 単語2

または

$ python wikisurf.py 単語1 単語2

のように実行します。すると単語1から単語2に至るまでの距離が分かります。例えば「相対性理論」から「川端康成」までの距離は3ワードでした。

$ ./wikisurf.py 相対性理論 川端康成
No.1 Distance: 0 Word: 相対性理論
No.2 Distance: 1 Word: 翻訳
No.3 Distance: 1 Word: 相対性原理
...
No.243 Distance: 2 Word: ユダヤ人
No.244 Distance: 2 Word: フリッツ・ハーバー
No.245 Distance: 2 Word: コロンビア大学
川端康成 found!
245 words searched.
Distance from 相対性理論 is 3

このように245単語のリンクを調べた結果、コロンビア大学と関係していることが分かりました。また、Graphvizというソフトで読めるDOT言語形式で、単語の経路をグラフ化する機能も付けてみました。このグラフを作るにはコマンドを

$ python wikisurf.py 相対性理論 川端康成 ファイル名.dot

にします。

ただ、これは取得したデータのほんの一部分しか表示していません。全てをグラフ化すると、情報量が多すぎてGraphvizが落ちてしまうからです。このグラフは「川端康成」に「相対性理論」との最短距離と同じ距離で到達するノードだけを表示したものです。実際には「相対性理論」からあらゆるノードへの経路があります。

今回作ったのは、以下のプログラムです。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from xml.dom import minidom
import re, urllib, urllib2, sys, time

def encode(str):
return urllib.urlencode({"": str})[1:]

def quote(str):
return str.replace('"', '\\"')

SPECIAL = encode("特別:データ書き出し")
USER_AGENT = "Mozilla/5.0"
MAX_COUNTS = 1000

class Timer:
def __init__(self):
self.time = time.time()
def wait(self, sec):
diff = time.time() - self.time
if diff < sec:
time.sleep(sec - diff)
self.time = time.time()

class Counter:
def __init__(self):
self._count = 0
def count(self):
self._count += 1
return self._count
def getCount(self):
return self._count

TIMER = Timer()
COUNTER = Counter()

class KWQueue:
def __init__(self):
self.queue = []
def enqueue(self, elt):
self.queue.append(elt)
def dequeue(self):
if len(self.queue):
elt = self.queue[0]
del self.queue[0]
return elt
else:
return None

class KWMap:
def __init__(self):
self.map = {}
def hasKey(self, key):
return (key in self.map)
def getMap(self):
return self.map
def get(self, key):
if key in self.map:
return self.map[key]
else:
return None
def set(self, key, value):
if key:

class KWLinkMap(KWMap):
def add(self, key, value):
if self.hasKey(key) and key: #keyが空でない場合
self.map[key].add(value)
else:
self.map[key] = set([value])

def getWordsForKeyword(keyword):
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', USER_AGENT)]

TIMER.wait(1)
try:
data = opener.open("http://ja.wikipedia.org/wiki/" + SPECIAL + "/" + encode(keyword))

lines = data.read()
dom = minidom.parseString(lines)
textDom = dom.getElementsByTagName("text")

if textDom: #記事がある場合
textData = textDom[0].firstChild.data
#print "Text data length: " + str(len(textData))
return set([w.split("|")[0].split("#")[0].encode("utf-8") for w in KW_PAT.findall(textData)])
except: #urlアクセスが失敗した場合
pass

return set() #記事がない場合

#GraphVizで表示できるdot形式のファイルを作る
def createDotFile(file, map, start, goal):

def loop():
key = queue.dequeue()
if not key:
return False

kid = nodeIds[key]

for word in map[key]:
if word: #空文字の場合は除く
if word in nodeIds:
wid = nodeIds[word]
else:
wid = "node" + str(len(nodeIds))
nodeIds[word] = wid

file.write("%s -> %s\n" % (wid, kid))
if (word not in words) and (word != start):
queue.enqueue(word)
words.add(word)

if start in map[key]: #このif文を省くとグラフが複雑になりすぎる
return False

return True

words = set([goal])
nodeIds = {goal:"node0"}
queue = KWQueue()
queue.enqueue(goal)

file.write("digraph g {\n")
file.write("graph [rankdir=LR]\n")

while loop():
pass

for key in nodeIds:
prop = "label=\"%s\"" % (quote(key))
if key == start:
prop += " color=red style=filled"
elif key == goal:
prop += " color=blue style=filled"
file.write("%s [%s]\n" % (nodeIds[key], prop))

file.write("}")


def main():

def loop():
word = kwQueue.dequeue()
if word:
level = kwLevelMap.get(word)
if cycle(word, level + 1):
return False
else:
print "A dead end!"
return False
return True

def cycle(searchWord, level):
print "No.%d Distance: %d Word: %s" % (COUNTER.count(), level-1, searchWord)
words = getWordsForKeyword(searchWord)
if COUNTER.getCount() >= MAX_COUNTS:
print "Reached to maximum access counts %d" % (MAX_COUNTS)
if goalWord in words:
kwLevelMap.set(goalWord, level)
kwLinkMap.add(goalWord, searchWord)
return True
else:
for word in words:
if word and (not kwLevelMap.hasKey(word)): #空白文字は除外
kwQueue.enqueue(word)
kwLevelMap.set(word, level) #最も早くでたlevelを採用
kwLinkMap.add(word, searchWord)
return False

file = None # dot file

try:
if len(sys.argv) > 2:
startWord = sys.argv[1]
goalWord = sys.argv[2]
if len(sys.argv) == 4: # When create dot file
file = open(sys.argv[3], "w")
else:
raise Exception
except Exception, e:
if e:
print e.message
print "USAGE: " + sys.argv[0] + " start-word goal-word [dot-file-name]"
exit()

kwLevelMap = KWMap()
kwLinkMap = KWLinkMap()
kwQueue = KWQueue()

kwLevelMap.set(startWord, 0)
kwLinkMap.add(startWord, None)
kwQueue.enqueue(startWord)

if len(getWordsForKeyword(goalWord)) == 0:
print "Cannot find " + goalWord + " on Wikipedia"
else:
# main loop
while loop():
pass

if kwLinkMap.hasKey(goalWord):
print goalWord + " found!"
print str(COUNTER.getCount()) + " words searched."
print "Distance from " + startWord + " is " + str(kwLevelMap.get(goalWord))

map = kwLinkMap.getMap()
if file:
createDotFile(file, map, startWord, goalWord)
else:
print "You Lose!"


if __name__ == "__main__":
main()


結局テーマの結論はまだ出ていないのですが、スタートとゴールの両方から攻めていった方がずっと効率的なことに後で気づきました。

2010年5月28日金曜日

プレゼン大会

企画部のキクチです。

今週は Sphia 4G サービスのコンセプトとサービス内容を固めるために、全員が各々で考えた内容でプレゼンするという試みをやっています。

企画部だけでなく開発部メンバーも基本は全員発表となりますので、面白いアイデアが出てきそうで楽しみです。

僕は発表の仕方は小説風味のストーリーテリングの手法を取り入れていこうかと思っています。
機能説明よりもユースケースを元に、感情に訴求するやり方でいこうかな~と。

今週の土曜定例に発表となるので、今から楽しみです。

自分が発表するのも楽しいですが、人の発表聞くにも楽しいですからね。
Sphia メンバーは突飛なアイデアが出てくることも多いので期待しちゃいます。

もちろん自分の発表も実のある楽しいものとなるようがんばりたいと思います。

2010年5月27日木曜日

挑戦

HootSuiteのCEO Ryan Holmes氏の話で印象に残ったこと。
(小学生の時にプログラミングを開始。16歳で起業!)

Don't be afraid of failure.
Follow your dream, don’t stop, listen to people with common sense and run away from the negative ones.

2010年5月26日水曜日

出会い

こんばんは、企画部の的場です。

毎回ブログにお付き合いいただき、ありがとうございます^^

今日は、読書について書こうと思います。


読者の皆さんも、多くの本を読まれていると思います。

僕も本は好きで、とても勉強になるので、1日に1冊を目標に読んでいます。

でも、ただ読むだけでは、あまり自分の身になっていないんじゃないか、というのが、僕が持っていた不安でした。

その不安をなくすために、僕がしている読書法は、以下のようなものです。


①読んだ本はすべて「ブクログ」に登録する。

②読んでいて「これは!」と思ったところはドッグイヤーしておく。

③後でドッグイヤーを見直して、時間があればPCでまとめを作る。


これくらいやると、さすがに本で読んだことが頭に入って、日常で使える気がします。

そう、僕が思うのは、勉強も読書も、何もかもが

「日常で使える」

ことがひとつの大きな目標だと思います。

でも、自分が読んだ本全部は持ち運べないし、覚えてもいられないです。

自分の読んだ本が、気に入った内容が、文言が、もっと簡単に見て、思い出すことができたら、僕はとっても嬉しいです。

それって、きっとウェブとかを使ったらできることなんだろうなって、ここのところずっと思っています。


今週末にはiPadも発売になります。

電子書籍時代の到来があって、自分の本棚をまるごと持ち運べるようになる時代は近いかもしれませんね♪

2010年5月25日火曜日

Wikipediaからキーワードを集めてみる

火曜担当の三森です。今夜はみんな大好きなWikipediaについて調べていました!そして、自分の指定したキーワードの記事の中から、関連するキーワードの一覧を取得するスクリプトをpythonの練習がてら書いてみました。今日はそれを紹介したいと思います。

Wikipediaの記事の内容を引用しているサイトは沢山ありますが、「wikipedia API」でググるとsimpleapiというサイトが筆頭に来ます。このAPIを使えば、キーワードに対して簡単なサマリーを取得することができます。
これでは情報量が少ないので全文をダウンロードしたいという時は

http://ja.wikipedia.org/wiki/特別:データ書き出し/<検索キーワード>

にアクセスすると、記事のXMLデータが取得出来ます。ただ、このページはブラウザからなら見られますが、自前のプログラムからだとアクセスが拒否されてしまいました。本家のサイトが本格的にAPIを提供できないということだと思いますが、練習ならいいだろうということでブラウザを装ってアクセスするスクリプトを書いてみました。

Wikipediaの記法では、記事が書かれているキーワードへのリンクは
[[<キーワード>]]
というパターンになっています。これを利用して、あるキーワードに関する記事の中で、既に記事が書かれている別のキーワードを見つけようというわけです。

先読み、後読みが使える正規表現なら

(?<=\[\[)([^\[\]:]+)(?=\]\])

のように書くと<キーワード>にマッチさせることができます。コロン(:)が入っている場合は特別な意味になるので、これも省くようにしています。

ではスクリプトのソースコードです。XMLをパースするminidom、正規表現のre、urlアクセスのためにurllib、urllib2
などのモジュールを使いました。


#!/usr/bin/env python
# -*- coding: utf-8 -*-

from xml.dom import minidom
import re, urllib, urllib2

def encode(str):
return urllib.urlencode({"": str})[1:]

SPECIAL = encode("特別:データ書き出し")
kw = encode("小室哲哉")
kw_pat = re.compile(r"(?<=\[\[)([^\[\]:]+)(?=\]\])", re.U)

opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
data = opener.open("http://ja.wikipedia.org/wiki/" + SPECIAL + "/" + kw)

lines = data.read()
dom = minidom.parseString(lines)
textData = dom.getElementsByTagName("text")[0].firstChild.data
words = kw_pat.findall(textData)
for word in words:
print word
print str(len(words)) + " keywords found!"


例えばキーワード「小室哲哉」で実行してみると

....
中田英寿
原田大三郎
DRAGON
坂本美雨
細木数子
スティーヴィー・ワンダー
スティーヴィー・サラス
高見沢俊彦
持田香織
1198 keywords found!

のように1198個ものキーワードリンクが見つかり、
かなりの人気記事であることが伺えます。

起業支援

『Open Network Lab』- グローバルな視点を持つ起業志向のエンジニアを支援
http://onlab.jp/concept.html

とっても面白そうですね!

---
http://joi.ito.com/weblog/2010/05/15/open-network-la.html

I look forward to seeing what sorts of people and ideas ONL is able to attract and hope that we can launch some stuff with global reach help put Japanese startups on the map Internationally.

2010年5月22日土曜日

javascript で REPL 環境構築 1

一週間ぶりのカメです。

javascript の開発ってみなさんどうやってます?
ちょっとした動作確認をするのにも
エディタで書いてブラウザで確認するっていうサイクルに不満を感じたことはありませんか?

そこで REPL 環境を構築することをおすすめします。

普段の javascript 開発ではこのようなサイクルでおこなっていると思います。
  1. お気に入りのエディタでガリガリと書いて
  2. ブラウザで確認

これを以下のサイクルに変更します
  1. お気に入りの設定を行った emacs でガリガリ書いて
  2. emacs で確認
素敵ですね。

javascript ってそもそもブラウザ上でしか動かないんじゃないのって疑問に思うかもしれません。
実はそんなことはなくてブラウザ毎の javascript 動作環境が単体で公開されているのです。

ブラウザと javascript 動作環境 の関係は以下のようになります。
  • safari -> KJS
  • Firefox -> SpiderMonkey, Rhino
  • Chromo -> V8
次回は、javascript 動作環境を実際にインストールします。

2010年5月21日金曜日

コンセプト

こんばんは。

企画部のキクチです。

最近の Sphia ですが、サービスのコンセプトについて、目下議論中です。

誰に対して、どのように、どんな感動を与えるか。

これを確固たるものにすべく全員で考えていますが、ちょっとここで他社さんのコンセプトを調べてみました。

-----------------------------------------------------------

mixi
「同じ趣味、同じ興味を持った人とつながろう」

GREE
「友達とのつながりをよりよいものにしていこう」

ECナビ
「買物をする時には必ず訪れてもらえるサイト」

ナビタイム
「人々の移動に「安心」を提供する」

マインディア
「あなたの脳から、みんなの脳へ。つながる辞典」

ランゲート
「外国語を学びたい世界中の人々が、それぞれの母国語を教えあうことで語学力を高める」

pixiv
「お絵かきがもっと楽しくなる場所」

-----------------------------------------------------------

どのサービスのコンセプトも分かりやすいですね。
それに見事にコンセプトを体現しています。

我々のサービス Sphia も明確なコンセプトの元、それを体現するサービスを目指していきたいと思います。

2010年5月19日水曜日

徒然なるままに

こんばんは、企画部的場です。
そろそろ水曜日の顔として、みなさんの中に定着できたでしょうか?

さすがにまだですかね。

まだの人、初めての人は、是非是非楽しんで読んでいってください。


今日は僕が暇なときにしてしまう時間つぶしと、勉強の関係について思ったところを書こうと思います。


僕は暇なとき

「ウィキペディア」で時間つぶしをします。

どうやってするかというと

1.適当な単語を検索する(昨日は「なす」と引きました)

2.その単語のページを読む(なすって、バラ科なんですよ!知ってました?)

3.気になったウィキペディア内のリンクに飛ぶ(バラ科に飛びました)

4.2に戻る

という具合で、どんどん飛んでいって、最初のページに戻ったり、面白くないページに行っちゃったり、飽きたら終わります。
これでだいたい1時間か2時間は暇つぶしができます。

で、これがなんで勉強の話につながるかということなんですが。


こうやってウィキペディアで見た知識って、すごく頭に残るんです。


別に検索してるのが医学用語でも、勉強で使うことでも意外と残ってるんですよね。
こう考えると、普段の勉強も、こういうふうにいろいろなところを見ながら勉強すれば、もっと楽しく、もっと効率良くできるんじゃないかって思うわけです。


そうです。


もう皆さんお気づきでしょう。

このような勉強を実現する仕組みが、僕らのサービスには入る予定です!

自分の興味を広げながら、知識がついて、さらに楽しい。

こんなにいいことないと僕は思います。



サービスのリリースまで、もう少しかかる予想です。

それまでは皆様、ウィキペディアでぜひ時間つぶしをしてみてはいかがでしょうか?

2010年5月18日火曜日

iPhone開発でメモリ使用量を把握しよう! 2

開発部の三森です。前回の続きです。
メモリ使用量を見るためにObjective-Cのランタイムapiを使ってみることを考えます。
Objective-Cで書かれたプログラムは、コンパイルされたプログラムだけでなく、ランタイムが必要になります。
このランタイムがオブジェクトの生成、メソッドの使用などをプログラムの実行時に動的に割り当てるようになっています。
そしてランタイムapiを使えば、オブジェクトのもつメソッドを自由に入れ替えたり書き換えたりできるのです。
どんなapiがあるかはAppleのドキュメントに詳しく書いてあります。

ランタイムapiを使うには、まず

#import <objc/runtime.h>

でヘッダを読み込みます。

オブジェクトのメモリ確保はNSObjectの持つ"+alloc"セレクターで行われるので、
これを新しいものに上書きしてデバッグ情報を得ることを目標にします。

今回はMemoryCheckSampleというiPhoneアプリのプロジェクトを作り、
MemoryCheckSampleAppDelegate.mというファイルのみを変更しました。
以下がそのファイルに新しく足した部分のソースコードです。


#import "MemoryCheckSampleAppDelegate.h"
#import <objc/runtime.h>

unsigned long GlobalMemoryCounter = 0;

@implementation MemoryCheckSampleAppDelegate

+ (void)load {
id meta = [NSObject class]->isa;
IMP oldAllocImp = class_getMethodImplementation(meta, @selector(alloc));
IMP newAllocImp = class_getMethodImplementation(self->isa, @selector(newAlloc));
Method m_oldAlloc = class_getClassMethod(meta, @selector(alloc));
Method m_newAlloc = class_getClassMethod(self, @selector(newAlloc:));
class_addMethod(meta, @selector(oldAlloc), oldAllocImp, method_getTypeEncoding(m_oldAlloc));
class_replaceMethod(meta, @selector(alloc), newAllocImp, method_getTypeEncoding(m_newAlloc));
}

+ (id)newAlloc {
id obj = [self oldAlloc];
NSLog(@"%@ allocated %zd", self, malloc_size(obj));
GlobalMemoryCounter += malloc_size(obj);
return obj;
}


+loadというのは初めにこのクラスがランタイムにロードされる時に呼び出されるセレクターです。
ここでNSObjectクラスの+allocの実装を+newAllocに入れ替えるということをしています。
+loadの一行目から説明すると

1. NSObjectのメタクラスがallocセレクターを持つので、それをmetaと呼びます。
2. 今までのallocセレクターで呼ばれるメソッドの実装を取り出し、oldAllocImpと呼びます。
3. このクラスのもつnewAllocセレクターの実装をnewAllocImpと呼びます。
4. 5. alloc, newAllocセレクターに対応するメソッドを取り出します(メソッドの型情報を取るために必要)
6. metaに今までのallocと同じ機能をもつoldAllocセレクターを追加します。
7. metaのallocセレクターで呼ばれるメソッドをnewAllocImpにします。

ということをやっています。今や+allocで呼ばれるようになった+newAllocの中でやっているのことは、
allocした後にそのオブジェクトのメモリーサイズをカウントするということです。
カウンターにはGlobalMemoryCounterというグローバル変数を使っています。試しに


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window makeKeyAndVisible];
NSLog(@"Allocated size : %ld", GlobalMemoryCounter);
}

と書いてみると、デバッグコンソールは

NSAutoreleasePool allocated 32
NSAutoreleasePool allocated 32
__NSPlaceholderArray allocated 16
__NSPlaceholderArray allocated 16
NSMutableArray allocated 16
WTFMainThreadCaller allocated 16
NSThread allocated 64
_NSThreadData allocated 96
NSMutableDictionary allocated 16
NSDate allocated 16

(... 大量のログ ...)

Allocated size : 4640

のようになり、ここまでで色々なオブジェクトを生成していることが分かります。

前回お話した

[UITableView alloc];
[[UITableView alloc] init];

の違いも見てみましょう。

見やすさのために以下のようにマクロを用意してLOG_ALLOC()マクロだけで見たい処理を書けるようにします。
LOG_ALLOC()を呼び出す度にGlobalMemoryCounter = 0でリセットします。

#define LOG_VOID NSLog(@"\n");
#define LOG_BAR1 NSLog(@"======================================");
#define LOG_BAR2 NSLog(@"--------------------------------------");

#define LOG_ALLOC(expr) LOG_VOID LOG_BAR1 NSLog(@"%s;", #expr); GlobalMemoryCounter = 0; LOG_BAR2 expr; \
LOG_BAR2 NSLog(@"Allocated size : %ld", GlobalMemoryCounter); LOG_BAR1 LOG_VOID

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window makeKeyAndVisible];
NSLog(@"Allocated size : %ld", GlobalMemoryCounter);

LOG_ALLOC([UITableView alloc]);
LOG_ALLOC([[UITableView alloc] init]);
}


ログの結果はそれぞれ

======================================
[UITableView alloc];
--------------------------------------
UITableView allocated 1024
--------------------------------------
Allocated size : 1024
======================================

======================================
[[UITableView alloc] init];
--------------------------------------
UITableView allocated 1024
CALayer allocated 48
UISwipeGestureRecognizer allocated 128

...

NSMutableArray allocated 16
UICachedDeviceRGBColor allocated 32
UICachedDeviceRGBColor allocated 32
--------------------------------------
Allocated size : 1696
======================================

これで違いが分かるようになりました。

2010年5月17日月曜日

概念モデルを言語化する

代表のしんです。

今でこそ僕は仲間とこのプロジェクトを推進していますが、
昔は「全部一人がいい!」
と思っていた人でした。

そして全部一人でやってました。

一人でのプロジェクトは、コミュニケーションコストが要りません。
人に伝える能力が要らないんです。

そして企画から開発、デザイン、普及、知財戦略まで全部自分でやるので
いろんな能力が身につきます。

それでも、人と一緒に開発する方が目的達成のためには断然よいです。

・マルチタスクになる
・アイデアにバラエティが生まれる
・得意分野の分業ができる

といったメリットは想像に難くないと思いますが、
今回は、一人のときには必要なかったコミュニケーションコストについて言及します。


人-人 間の詳細な意思疎通には言語が不可欠です。
もやもやした脳内の概念モデルをそのまま共有することはできません。
それらを言語に落とし込む作業を経ることではじめて、
異なる人間が同じ概念を共有できるのです。


実はこの「脳内の概念モデルを言語に落とし込む作業」は、
プロジェクトを見つめるうえでとても重要なのです。

一人の開発のときには、もやもやした概念モデルを言語化することなく
サービスを考え、プログラムを組み、デザインを描いてきました。
確かにコミュニケーションコストはかかりませんが、
概念モデル自体がクリアでないため、開発スピードは必ずしも早いとはいえませんでした。
それらを言語に落とし込む作業によって、目指すべき方向性をクリアにし、
開発に専念することができるようになるのです。

よって、一人で開発するにしても、概念モデルの言語化は不可欠です。
だからコミュニケーションコストがかからないというわけではないようです。

概念モデルが適切に言語化でき、複数人の間で共通の理解が得られているプロジェクトは、
きっと一人で開発するスピードの数十倍ほどの効率が得られそうです。

人脈について

こんばんは。企画部リーダーの長谷です。

今日は、人脈について考えてみました。

そもそも人脈ってなんでしょうか?人脈ってどういう風に使うんでしょうか?

漫画とかの中では、人脈一つで権力を握っている関係がよく描かれていて、人脈の大切さがわかります。実際、そういう場面は存在するのだろうし、そういう人って見かけるなとも思います。

でも、ただその人を知っている。顔を合わせたことがある程度の人を人脈と呼べるかと言ったら、100%違うと言えるでしょう。

自分もこういう活動をやっていると、色んな人に会ってアドバイスをいただくことが多いのですが、それって人脈かと聞かれれば、かなり微妙なところです。

ある本には、人脈作りで大事なことは”関係の継続化と固定化である”と書いてありましたが、それって本当に大変なことだと思います。

そこで、自分なりに考えた結果、”頼みごとができる関係”というのが人脈ではないかと仮説をたてました。

友達の中にも、頼みごとがしやすい人間と、そうでない人間がいると思いますが、そのしやすさは仲の良さに比例すると思います。

じゃあ、人と”頼みごとができる関係”になるにはどうしたらいいのでしょうか?

それは自分が”頼みごとを聞いてあげる”ことです。

じゃあ、どうしたら”頼みごとをしてもらえる”のでしょうか?

それは、”自分の中に確かな力をもつこと”です。

力を持つことと、頼みごとを聞いてあげること、これが人脈作りの早道なんじゃないでしょうか?

もちろん、そんな打算的に頼みごとを聞いていたら、向こうだって頼みごとがしづらいのでよくないですが、一つの真実だと思います。

今現在、自分はなんの力も示せてません。例えば、てっとり早く会社を立てて登記まですれば一つの力の証明になるかもしれません。

起業をすることのメリットの一つはここにあるのかもしれませんね。

2010年5月15日土曜日

クロージャの解説

カメです。
さっそくですが、前回の NG コードを元に解説を行います。


var DynamicWrapper = function(_targetObj, _wrapperObj){
var wrapped = eval("(" + _targetObj.toSource() + ")"); // deep copy
for(var memberName in _targetObj){
if(typeof(_targetObj[memberName]) == "function"){
wrapped[memberName] = function(){
_wrapperObj.before(memberName);
var result = _targetObj[memberName].apply(_targetObj, arguments);
_wrapperObj.after(memberName);
return result;
};
}
}
return wrapped;
};


NG コードの流れは言葉で書くと以下のようになるでしょう。
  1. 引数として受け取った "_targetObj" のコピーを作成する
  2. "_targetObj" の要素ごとにループを開始する
  3. "_targetObj" の要素が "function" の場合以下の処理を行う
    • "_targetObj" のコピーに"_targetObj" の要素名で、ラップされた関数を定義する
  4. "_targetObj" の要素がなくなるまで、ループを継続する
  5. "_targetObj" のコピーを呼び出しもとに返す

でも実際には、落とし穴があるのです。
"_targetObj" のコピーに"_targetObj" の要素名でラップされた関数を定義する
コードでは以下の部分


wrapped[memberName] = function(){
_wrapperObj.before(memberName);
var result = _targetObj[memberName].apply(_targetObj, arguments);
_wrapperObj.after(memberName);
return result;
};

上記のコードの "function()" は上位の "function()" 内に存在するため、上位 "function()" 内の環境による影響を受けます。
そのため、変数 "memberName" は 上位の "function()" 内で宣言されており、その影響を受けます。
よって、"wrapped[memberName]" の "memberName" はループ実行時の値ですが、
"function()" 内の "memberName" は関数呼び出し時の "memberName" が使用されるのです。
# 関数呼び出し時の "memberName" は、今回ではループに使用された最後の値
そのため、呼び出した関数と、呼ばれた関数に乖離が生じていたのです。

どうでしょう?

みなさんのコードでループ内でちょっとかわったことをした際に、予想と違う動きをされたことがあるかもしれません。
そのときは、今回のようなクロージャが影響しているかもしれませんよ?

2010年5月14日金曜日

キックオフ

こんばんは!

企画部のキクチです。

今週日曜には現 Sphia メンバーでのキックオフミーティング(飲み会)が
あります。

僕が今までプロジェクトをいくつか手がけてきて成功するプロジェクト
に共通していると思うものに以下の事柄があります。

1. プロジェクトのゴールが明確であり、メンバー全員にその意識がある
2. スケジュール管理、タスク管理、リスク管理が適切にされている
3. タスクに担当と期限と消化条件が定まっている
4. コミュニケーションを綿密にとっている
5. キックオフミーティングとクロージングミーティングを省くことなく
実施されている

たかが飲み会ですが、メンバーの特性やバックグラウンドを知り、コミュ
ニケーションを活性化させる意味では、うってつけの方法だと思います。

これを機にさらにサービス開発を加速させていきたいところです。

では、今日はこの辺で。

2010年5月12日水曜日

勉強に使う道具って?

こんばんは。
企画部の的場です。先週の水曜日ぶりですね。

今日は、僕の勉強法について、一つご紹介したいと思います。
みなさんに、お聞きしたいことがあります。


Q1:勉強を何を使ってやっていますか?


勉強っていったら、教科書と紙とペンでしょ!当たり前でしょ!!
と言われそうです。
では、質問2つ目です。


Q2:なんで、パソコンを勉強に使わないのですか?



え、紙のペンの方が使いやすいじゃん。
とか
パソコン重いしめんどくさい。。
とか
データが飛びそうで信用できない!

色々ありますね。

でも、僕はパソコンで勉強もなかなかいいと思うんです。
実際に去年度の春に、パソコンで、自分たちのデモサイトを使ってテスト勉強してみました。

それまでは、バリバリの紙ペン派だったんです。

「パソコンでノートとっても覚えられる分けないじゃん」

って本気で思ってました。




でも、使ってみたら、意外だったんですが、キーボードで打ち込んでも意外と覚えられました!
おかげで、試験もすべて通すことができました(本当です。)

もちろんブラインドタッチができないと、書くのは遅くなるし、図とかは入れにくいんですけどね。。。

でも、分からないことがあったら、すぐにインターネットで調べられたり、疲れてきても、文字が汚くならないとか、利点もたくさんあるんです。

ちょっと、とっつきづらい感じもあるかもしれませんが、ぜひ一度、パソコンでの勉強、試してみてはどうでしょうか?
新しい発見があるかもしれませんよ!

ではでは、また来週の水曜日にお目にかかれればと思います。
失礼します。

2010年5月11日火曜日

iPhone開発でメモリ使用量を把握しよう!

開発部の三森です。雨の日は室内での作業がはかどる気がします。
前回の予告通り、今回からは技術っぽい記事を書きます!

というわけで、今をときめくiPhoneの地味なメモリ管理のお話です。
iPhoneはとても贅沢にメモリを使える環境ではないので、
何にどれぐらいメモリを使っているか正確に把握したいところです。

しかし、Cocoaフレームワークのクラスはブラックボックスですし、
そもそもオブジェクトを作るのにどれぐらいメモリを使ってるのか、
調べるのも面倒なので僕は把握していませんでした。

メモリ使用量が定量的に分からないために、
どんな実装をすべきかをわりと感覚的に判断してしまっていました。。

これはいか〜ん!ということで、今回は真面目に考えてみることにします。
個々のオブジェクトがどれだけメモリーを確保するかを見てみましょう。

まず、sizeof演算子で見てみると


NSLog(@"%ld", sizeof([NSObject alloc]));


デバッガコンソールでは以下のような感じ:

2010-05-11 23:03:00.614 MemoryCheckSample[7432:207] 4


で、4バイトであることが分かります。
しかし、これはNSObjectインスタンスへのポインターのサイズなので、意味がありません。
知りたいのは確保されたオブジェクトのサイズなので、malloc_sizeを使います。
UITableViewが継承しているクラスを親から順番に見てみましょう。


NSLog(@"%ld", malloc_size([NSObject alloc]));
NSLog(@"%ld", malloc_size([UIRespondor alloc]));
NSLog(@"%ld", malloc_size([UIView alloc]));
NSLog(@"%ld", malloc_size([UIScrollView alloc]));
NSLog(@"%ld", malloc_size([UITableView alloc]));


デバッガコンソールを見ると

2010-05-11 23:09:59.353 MemoryCheckSample[7467:207] 16
2010-05-11 23:09:59.356 MemoryCheckSample[7467:207] 16
2010-05-11 23:09:59.359 MemoryCheckSample[7467:207] 48
2010-05-11 23:09:59.361 MemoryCheckSample[7467:207] 400
2010-05-11 23:09:59.367 MemoryCheckSample[7467:207] 1024


と、段々増えていっていることが分かります。
これはインスタンス用に確保したメモリーが見えています。
あとでObjective-Cのランタイムの実装ファイルを見たのですが、
オブジェクトのメモリは16バイト単位で確保されているようです。

これを見るとUITableViewに至っては1Kバイトも使われていますが、
NSObjectを沢山作る分には、メモリ的な心配はあまりなさそうです。
どちらかといえば、生成時間がかかることが問題かもしれません。

ところで、お気づきかもしれませんが、
これはまだ本当に使用したメモリーを見ているとは言えません。
なぜなら、各インスタンス変数にもオブジェクトが含まれているはずなのですが、
それらを生成するメモリ量をカウントしていないからです。例えば


[[UITableView alloc] init];


などとすると、initの中でオブジェクトが何か作られているはずですが、
malloc_sizeで見てもメモリ使用量は変わっていません。

そこで、開発部の亀田のAOP(Aspect Oriented Programming)に触発されて
NSObjectのallocを上書きするということをやってみました。
長くなってしまったので、そのお話は次回書こうと思います!

夢への目標

企画部の長谷です。。

今日、人と話していて思ったことを一つ。

普通、将来のことを考えているって言うと、どんな思考プロセスを思い浮かべるでしょうか?

一般的には、、、

今の現在がこんな感じだから

次に起こる選択肢はこういうのが予想されて、、

次の10年はこんな風に生きて

次の選択肢はこんな風に選んで…

結果、こんな感じの未来を想定しつつ生きよう。

こんなとこだと思います。

しかし、僕はこれは違うと思うのです!!

僕はこうあるべきだと思うのです!!

まず、高い理想。こんな自分はかっこいい!!こんな自分になりたいってのを具体的にイメージする。

今の自分を評価する

達成するためには何が必要か?

じゃあ、それをやろう!

当たり前だろと言う方もいるかと思いますが、意外とみんなやっていません。
でも、こういう思考プロセスを経ないと、本当に合理的な発想ってできないと思うんですよね。

これは、ビジョナリーカンパニーにも通ずるものがあると思います。

自分の思考プロセス、どんな感じになっているのでしょうか?みなさん、よければ教えてください。

2010年5月9日日曜日

カッコいい勉強

Sphia代表のしんです。

今日は町田のカフェで作業。

学生時代はカフェやファミレスで作業することはほとんどなく、
ひたすら家でコーディングしてたんだけど、
最近だんだんカフェに行くようになってきた。
(家がネットつながらないんで)


丸いテーブルで60-70代ぐらいの男性が本を読んでいた。
小説にしては大きいし、ハードカバーでもないし、横書きだ。

チラリと中を見てみると、
∫←こんな記号がひたすら並んでいる数学の本だった!
(物理の本かもしれない!)

僕はそれを見てとてもハッピーな気持ちになった。

その人が理系の研究者である説も全然捨てきれないけど、
その年になっても精力的に学問をつき進めてゆく姿勢。
いつになっても学びってやっぱり大事なんだな!って思えた。

他にも学生や社会人が各々、英語や法律、経済などの学びに勤しんでいた。

街に出たから分かった。

学びたい人は結構いるぞ!


僕らは、サービスを提案するたびに
「勉強したい人、がターゲット?それはビジネスを考えてない。
そんなやつほとんどいないんだって。お前らは医学部だから特殊なんだよ」

と言われ続けてきた。


とても寂しかった。
勉強をしたい!という欲求が、どこか社会通念みたいなものに
抑圧されている感があったから。

社会で成功を収めている「イケてる」人たちはもしかしたら、
「学校の勉強など無意味。社会に出てからがすべて」というかもしれない。
「学生時代はとにかく遊べ!社会経験積め!
  机上の空論なんて意味ないからな!」

と、カッコ良く語るかも知れない。

こういった表現は、勉強するという行為を、泥臭くてカッコ悪くて
究極の遠回りなものにしてしまう。

ではそれは本当なの?
勉強するという行為は、泥臭くてカッコ悪くて、究極の遠回りなの?

もちろん社会経験とか遊びとか実務的なこととか、
必要なものは勉強以外にもたくさんある。

でもそれは勉強が意味ないということとは別次元の話。
どっちも大事なんだよ。
大事だから、高齢になっても自発的に勉強してるんだよ。

勉強ってカッコ悪いみたいなイメージを払拭すれば、
きっともっと多くの人が堂々と勉強するんじゃないのかな?

僕はSphiaという活動を通じて、
勉強する全ての人に、coolな勉強法を届けたい。
社会全体が、少しでも「勉強って、楽しくて、カッコいいもんだ!」
っていう認識になってきたら、きっと日本は良くなっていくと思う。

2010年5月8日土曜日

開発部のカメです。

はじめまして、開発部のカメです。
土曜日担当です。

三森さんと同じく物理をやっていました。
でも、院生のころに物理のセンスがない頃に(ようやく)気づき、
社会人になっても継続して勉強できる対象としてプログラミング言語 をやることにしました。

でいろいろあって、ご縁があって Sphia の仲間入り。

全然関係ないですが、 emacs 使いです。
Sphia では vi 派が多くちょっと肩身が狭いです。

せっかくですのでちょっと JavaScript のネタを一つ、クロージャに関することです。
関数を作ります、いわゆる AOP。条件は以下の通り。
・指定したオブジェクトのすべての関数の呼び出し前と後に、処理を追加したい。
・指定したオブジェクトのソースは変更したくない。
簡単に書くと以下のようになります。(FireFox向け)

var DynamicWrapper = function(_targetObj, _wrapperObj){
var wrapped = eval("(" + _targetObj.toSource() + ")"); // deep copy
for(var memberName in _targetObj){
if(typeof(_targetObj[memberName]) == "function"){
wrapped[memberName] = function(){
_wrapperObj.before(memberName);
var result = _targetObj[memberName].apply(_targetObj, arguments);
_wrapperObj.after(memberName);
return result;
};
}
}
return wrapped;
};

具体的な使用方法は、まず呼び出し前後に行う処理を定義したクラスを作成します。

var Wrapper = function(){
this.getDate = function(){
var date = new Date();
return date;
};
this.before = function(_functionName){
var date = this.getDate();
alert(date + ":" + _functionName + ":" + "start");
};
this.after = function(_functionName){
var date = this.getDate();
alert(date + ":" + _functionName + ":" + "end");
};
};

次に実際に処理するクラスを作成します。今回は簡単にsetter/getterを持った人クラスとします

var Person = function(){
this.name = "";
this.getName = function(){return this.name;};
this.setName = function(_name){this.name = _name;};
};

最後に Person クラスの関数 getName, setName の呼び出し前後に、Wapper クラスで定義した関数を呼び出させましょう

var wrapper = new Wrapper();
var person = new Person();
var wrappedPerson = new DynamicWrapper(person, wrapper);
wrappedPerson.setName(”カメ"); // 呼び出しの前後に、wrapper.before("setName")/wrapper.after("setName")が呼ばれる...
alert(wrappedPerson.getName()); // 呼び出しの前後に、wrapper.before("getName")/wrapper.after("getName")が呼ばれる...

実行するとなんか変ですね。
alertに表示される関数名が呼び出した関数名と異なる場合があると思います。
正確に書くと wrappedPerson.getName() を呼び出しても、 wrappedPerson.setName() を呼び出しても同じ関数が呼ばれます。
原因は DynamicWrapper クラスに存在し、クロージャを意識していないためです。
修正版の DynamicWrapper クラスは以下のようになります。


var DynamicWrapper = function(_targetObj, _wrapperObj){
var wrapped = eval("(" + _targetObj.toSource() + ")"); // deep copy
for(var memberName in _targetObj){
if(typeof(_targetObj[memberName]) == "function"){
wrapped[memberName] = (function(){ // 環境に束縛
var funcName = memberName;
var func = _targetObj[funcName];
return function(){
_wrapperObj.before(funcName);
var result = func.apply(_targetObj, arguments);
_wrapperObj.after(funcName);
return result;
};
})();
}
}
return wrapped;
};
長くなりましたので、解説は(要望があれば)次回に

2010年5月7日金曜日

金曜日担当です!

こんばんは!

企画部のキクチです。
当ブログの金曜日担当です。

三森と同じことを書きますが、sphiaでは医学生が多いですが、
僕は医学ではなく数学をやってました。

そしてsphiaでは唯一の現役社会人でもあります。
某企業でネットワークコンサルタントとして働いています。

「インターネットサービスの便利さを多くの人に味わってもら
いたい!そのための道であるネットワークをもっともっと提供
したい!」
と思い、今の仕事をしています。

ですが、インターネットサービスそのものも作ってみたい、と
フツフツと考えたときにsphiaメンバーに出会い、参加すること
にしました。

sphiaでは技術サイドではなく、企画の仕事を主にしていきます。
二足のわらじを履くことになりますが他のメンバーに負けない
ようがんばっていきます!

今後の金曜日は、企画部の仕事模様と、せっかくなのでたまに
ネットワーク話も挟みながらお伝えしていこうかと思います。

では、今日はこの辺で。

2010年5月6日木曜日

iPhone開発担当、阿部です

どうも初めまして。一応開発部の阿部です。
一応と申しますのは、僕はこれまでプログラミングの経験がなく、
一ヶ月前からやっとiPhoneアプリ開発の勉強を始めたばかりだからです。
それでも、先日当ブログを書いた三森さんから丁寧に説明していただき、
少しずつ理解を深めている、文学部の端くれです。

僕がSphiaというチームと出会ったのは、
そしてSphiaというサービスを知ったのは、
とあるビジネスコンテストにおいてでした。
全くの未知の気づきを得るという、
Googleですら難しいことを実現しようとしていました。

僕はその時の感動を忘れることができません。
想像を超えている、そんな風に感じました。
頭の中で想像したことは実現できる。
できないことなんてない。
そんなことを知った時でした。

全くのプログラミング未経験の僕を、
仲間として迎えてくれたSphiaには本当に感謝しています。
まだまだ役立たずですが、
早く技術的に貢献したいです。
木曜の僕が書くときは、
主にiPhoneアプリ開発についての内容になります。
僕も勉強していくので、
どうか読んでくれたら嬉しいです。

よろしくお願いします。

2010年5月5日水曜日

はじめまして!

こんばんは
日頃Sphiaをご愛玩なさっていただき、ありがとうございます。

企画部に所属しております、慶応大学医学部6年生の的場優介と申します。
本日は、僕がなぜSphiaに関与するようになったか、またこの会社にかける夢をお話しできればと思います。
twitterよりは長い文章になりますが、おつきあい頂ければ幸いです。

僕のSphiaとの関係は、同級生で同じ企画部のはせに誘われるところから始まりました。
Sphiaのポスターを作って欲しいとのことで、頼まれたのです。
僕自身、イラストやデザインといった分野に興味があったので、手伝うことにしました。

ここで初めてSphiaと出会って、僕はその魅力にとりつかれました。
それは、Sphaiを使うことで、人々がより簡単に教養を身につけることができるのではないかと考えたからです。


多方面からの、幅広い、ある程度の深さの知識を身につけることは非常に困難です。

でも、Sphiaの機能を使えば、一気にいろいろな視点からの、専門家の意見をみることが出来る。

これは、僕自身が欲しく、また、あらゆる人のためになると確信しました。
これが、僕がSphiaに感じる魅力であり、またSphiaが実現できればいいなと思うことです。


僕自身、技術のことはあまり分かりませんが、これから勉強して、ユーザーと技術者の架け橋になっていこうと思います!
御意見ご感想ご叱責、おまちしていまっす!

2010年5月4日火曜日

メンバー紹介その3

はじめまして。開発部の三森です。
sphiaのメンバーは医学生が多いのですが、
僕はもともと物理をやっていました。
ちなみに趣味はピアノです。

僕は社会人になってプログラムの仕事を始めた頃から、
みんなが日常的に使えるソフトやサービスを作りたいと思っていました。
それは例えばweb検索やgoogle maps、gmailなど、(例がgoogleばかりですが)
一つのアイディアを深めて生活の一部となったモノのことです。
そしてその目標に近づくための道を模索していました。

そんな中、学習をサポートするwebサービスで起業するsphiaのメンバー
に運命的に出会い、開発に参加することになりました。
このsphiaで、紙の上での勉強やノート系のwebサービスよりも
もっと勉強に適したサービスを作っていきたいと思っています。

次回から僕はsphiaの開発で学んだ技術ネタを紹介していく予定です。
よろしくお願いします。

団体紹介(企画部リーダー:ハセ)

こんにちは。
企画部リーダーのハセ(24)です。

今日は、団体Sphiaについてもう少し詳しく紹介したいと思います。

まず、Sphiaが団体としてどういう事を目指しているかといいますと…、ずばり、

“賢い人を増やす”

です!!

え?賢い人ってどういう事かって?
う〜ん、そこが確かに難しいところです。ただSphiaでは、

“今まで学んできた事を、新たに学んだ事と融合させて、新たなる価値を生み出す事のできる人”

のことを、とりあえず“賢い人”って呼ぶことにしています。

実は僕は、医学生なんですよ。現在6年生です。この団体は、そもそも前身を僕が4年生の終わりの時に作りまして、医学生のためにもっと勉強に役立つサービスを作りたいなってとこから始まり、5年生の時に“しん”と出会って、紆余曲折を経て今の形になってるわけです。

医学部では、ただ勉強したことを丸暗記するだけでは、なかなか後の人生にはそれを役立てることができないのは、なんとなくみんな賛成してくれると思います。

しかし、丸暗記せざるを得ない量の勉強量があるのもまた現実なんですよ。僕たちは、こんな現実が嫌で、今のサービス•団体を作りました。

そこから派生して、賢い人ってなんだろう?それを実現するためにはどうしたらいいんだろうって思想に発展したわけです。

現在Sphiaは、二つの部署に分かれて仕事をしています。一つは、企画部。もう一つは開発部です。

企画部では、主にサービスの内容についての吟味を行っています。どんなサイトにするか?これはどんな人に役立つのか?そんな人はどれだけいるのか?こんな問いに答えられる様にするのが企画部の仕事です。

開発部では、主にサービスの作り込みを行っています。企画部の提案した案を実現するのが、開発部の仕事です。プログラミングに強い技術者集団がここにいます。なんとも頼れる人達です。

このブログは、企画部と開発部の人間が基本交互に書いていくので、みんな応援してくださいね。これからもよろしくお願いしますね。

2010年5月2日日曜日

やります。

こんにちは!
[学習×Web]というコンセプトでサービスを作ろう!ということで集まった団体、Sphiaです。
まだ出来上がって間もないですが、
日々学んでいるみなさんの満足するサービスを提供できるまで、
決して諦めずに励んでいこうと思っています!


そんな代表の鈴木晋(しん、24)です。


今日は初めてのブログなので、
僕の経歴について話そうかなと思います。

僕の経歴は…はっきりいってつまらないです、今年の3月までは。
でも4月からの経歴を合わせると、
世の中に同じ経歴の人はきっとほとんどいなくなるでしょう。

僕は岩手県に生まれ、高校まで岩手県盛岡市で過ごしました。
高校は盛岡第一高校という県内一の進学校。
夢は研究者でしたが、父に医師をすすめられ慶應義塾大学医学部に入学。

在学中にWebプログラミングに出会いました。
これが僕の転機になりました。
なんかWebで、コンピュータで、きっと面白いことができる!と感じ、
当時入っていたヨット部をやめて、プログラミングを始めました。(3年の終わりぐらいに)

プログラミングを学ぶ中で、「勉強してもなんか覚えられん」を、プログラムで
解決できないか、と思うようになりました。
医学は覚える量が膨大で、知識のつながりが特に重要な分野です。
しかし、毎回のテストを乗り切るだけでは全然体系的に把握できないなぁと不満だったのです。

それを解決すべくWebアプリを作っていく過程で、
共感してくれる後輩たちと出会いました。

色々な出会いのなかで、そのアプリのビジネスコンテストなどに出る機会があり、
ついには1000万円の出資の話を頂くことができました。(6年3月時)

僕は病院への就職が決まっていましたが、
一度しかない人生で、こんな面白い機会を無駄にするのはもったいない!と思い、
医学の道を諦めて起業することにしました。


といいつつ現在はまだ準備期間で、起業していません。
今は面白法人カヤックというWeb制作会社で「留学」させていただいています。
とても貴重な経験です。

留学期間を終えた7月を目標に、仲間と起業準備を進めています。

会社運営のことも、プログラミングのことも、Web業界のことも、
正直まだ分からないことばかりです。


でも、だから何?という気持ちでいます。
サービスを本気で世に出したいという気持ちが一番大事だと思っています。
そのほかの分からないことは、躓きながら乗り越えてゆくものだと思っています。



毎日、このプロジェクトの仲間たちとこのブログで情報を発信してゆきたいです。