ラベル プログラミング の投稿を表示しています。 すべての投稿を表示
ラベル プログラミング の投稿を表示しています。 すべての投稿を表示

2015年5月15日金曜日

Androidアプリの背景を透明に

Androidで画面が透過されたActivityを作るには、AndroidManifest中の、該当activityの設定に
android:theme="@android:style/Theme.Translucent"
または、
android:theme="@android:style/Theme.Translucent.NoTitleBar"
を追加します。

一瞬たりとも黒い画面になることなく、できます。

これ、すごい面白いことできそう

UIの必要ないActivityを作るのにも使えそうですし、普通にその上に文字とか書いても面白そう

参考:
http://www.adakoda.com/android/000265.html

2015年5月12日火曜日

AndroidのBitmap+Matrixの回転の中心は何処?

Android Studioでの開発は、クールではないですが、Android SDKに関するドキュメントはとても体系的にまとめられており、わかりやすいです。
で、それを読んだにも関わらずはまったこと。
Matrix matrix = new Matrix();
matrix.setRotate(45, bitmap.getWidth()/2,bitmap.getHeight()/2);
canvas.setMatrix(matrix);
canvas.drawBitmap(bitmap, width-bitmap.getWidth(), height-bitmap.getHeight(), null)
を実行した時、matrixがいつかけられるのかという話。

開発している時、ずっとmatrixをかけてから描画するものだと思い、回転の中心を画像の中心のつもりで値を設定していました。 それにも関わらず、回転しかさせていないのに何故か移動する! 不思議すぎて不思議すぎて悩んでいると、なんと描画してから回転のようで、回転の中心を画面全体の絶対座標にするとちゃんとできました・・・

これで解決!

2015年4月18日土曜日

FabricでTwitter with Swift(iPhone)

Fabricを使って、Twitterクライアントを作る方法(Swift)



いろいろフレームワークがしてくれて楽なのですが、まだまだ未完成のようで、あまり機能がありません・・・
また、公式ドキュメントも一部Objective-Cしかなく、頼りないです。

ただし、セルの高さの計算・アイコン画像の非同期受信などはすべて自動で行ってくれます。ログインボタンもとても簡単に実装することができます。


Qiitaー[iOS]FabricでTwitterクライアントを作った
このページがとてもわかり易いです。Fabricの適用方法などはこちらを参照してください。

このページのTwitterAPI.swiftを拡張して、サーチ・投稿・IDによるツイートの取得の関数を追加しました。

GitHub上に公開しています。
https://github.com/ha1fha1f/Lit_final/blob/master/TwitterAPI.swift

以下、上のAPIを用いたデータの保持・取得を行うクラスの例です。(2015/4/17現在)

import Foundation
import TwitterKit

class TweetDataModel :NSObject{
    
    var tweets:[TWTRTweet]
    
    // initialize
    override init() {
        self.tweets = []
    }
    
    func fetchTimeline(maxid:String?){
        TwitterAPI.getHomeTimeline({
            twttrs in
            
            println("fetch")
            
            if self.tweets.count == 0 {
                self.tweets = twttrs
            }else{
                let tmptweets:[TWTRTweet]
                
                if twttrs[0].tweetID > self.tweets.last?.tweetID {//新しいツイートがある
                    tmptweets = reverse(twttrs)
                }else{
                    //if twttrs.last?.tweetID < self.tweets[0].tweetID{//古いツイートがある
                    tmptweets=twttrs
                }
            
                for tweetCell in tmptweets {
                    if tweetCell.tweetID > self.tweets[0].tweetID {//新ツイートを上に追加
                        self.tweets.insert(tweetCell,atIndex: 0)
                    }else if tweetCell.tweetID < self.tweets.last?.tweetID {//古いツイートを下に追加
                        self.tweets.append(tweetCell)
                    }
                }
            }
            println("finish")

            //notificationを送る
            NSNotificationCenter.defaultCenter().postNotificationName("tweetLoaded", object: nil)
            
            },
            maxid: maxid,
            count: "40",
            error: {error in println(error.localizedDescription)})
    }
}
ご参考までに。
これは.Darkのテーマでの表示です!

セルのテーマカラーは二種類用意されています。.Darkと.Lightです。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! OriginalTweetTableViewCell
        
        println("\(indexPath.row)")
        
        if tweetData.tweets.count > indexPath.row {
            let tweet = tweetData.tweets[indexPath.row]
            cell.tag = indexPath.row
            cell.configureWithTweet(tweet)
            cell.tweetView.theme = .Dark
            cell.delegate = self
        }
        
        return cell
    }
のように、セルを返すときに、tweetView.themeを設定すればよいです。

僕の場合はTWTRTweetCellを継承したオリジナルのクラスを作ったのでやや異なりますが、設定方法などはだいたい同じです。
(https://github.com/ha1fha1f/Lit_final/blob/master/Litfinal/OriginalCell.swift)

雑になってしまいましたが、終わります

2015年4月17日金曜日

Swift(iPhone)での形態素解析〜NSLinguisticTagger〜

iPhoneにmecabのframeworkが搭載されているのは見えるが、公式のリファレンスがなく、使用することができない。

しかし、それ以外の(?)形態素解析を用いることができる。
iOS 5.1から搭載されているが、紹介記事が少ないので。

        var testString="iPhoneでも形態素解析を手軽に、だれでも行うことができます。ただし、日本語の場合、機能制限が多いです"
        let tagschemes = NSLinguisticTagger.availableTagSchemesForLanguage("ja")//取得するだけ
        let tagger = NSLinguisticTagger(tagSchemes: tagschemes,options: 0)//インスタンス作成
        let options: NSLinguisticTaggerOptions = .OmitWhitespace | .OmitPunctuation | .JoinNames
        tagger.string=testString//文字列をセット
        tagger.enumerateTagsInRange(NSMakeRange(0, (testString as NSString).length), scheme: NSLinguisticTagSchemeTokenType, options: options) {
            (tag, tokenRange, sentenceRange, _) in
            let token = (self.testString as NSString).substringWithRange(tokenRange)
            println("\(token): \(tag)")
        }
たったこれだけ。

NSLinguisticTagger.availableTagSchemesForLanguage で取得できるのは、使える機能のリストです。
日本語("ja")では[TokenType, Language, Script]
英語("en")では[TokenType,Language,Script,Lemma,LexicalClass,NameType,NameTypeOrLexicalClass]
が返ってきます。

一般的な形態素解析(品詞まで分解)はNSLinguisticTagSchemeLexicalClassです

日本語に対してできる最大限、NSLinguisticTagSchemeTokenTypeを行うと、文をトークンに分割したものを出力してくれます。"tag"は基本的に"Word"になっています。

何かに使えればいいな。

ただし、認識精度は非常に低いです。。。
token= 今日: Word
token= : Word
token= : Word
token= : Word
token= 天気: Word
token= です: Word
token= : Word
token= なんで: Word
token= : Word
token= : Word
token= : Word
token= 同じ: Word
token= 単語: Word
token= : Word
token= : Word
token= : Word
token= 認識: Word
token= : Word
token= : Word
token= ない: Word
token= : Word
token= じゃ: Word

mecabなら
今日はいい天気ですね
今日 名詞,副詞可能,*,*,*,*,今日,キョウ,キョー
助詞,係助詞,*,*,*,*,は,ハ,ワ
いい 形容詞,自立,*,*,形容詞・イイ,基本形,いい,イイ,イイ
天気 名詞,一般,*,*,*,*,天気,テンキ,テンキ
です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
助詞,終助詞,*,*,*,*,ね,ネ,ネ
EOS
なんで「いい」が同じ単語として認識されないんじゃ
なんで 副詞,一般,*,*,*,*,なんで,ナンデ,ナンデ
記号,括弧開,*,*,*,*,「,「,「
いい 形容詞,自立,*,*,形容詞・イイ,基本形,いい,イイ,イイ
記号,括弧閉,*,*,*,*,」,」,」
助詞,格助詞,一般,*,*,*,が,ガ,ガ
同じ 連体詞,*,*,*,*,*,同じ,オナジ,オナジ
単語 名詞,一般,*,*,*,*,単語,タンゴ,タンゴ
として 助詞,格助詞,連語,*,*,*,として,トシテ,トシテ
認識 名詞,サ変接続,*,*,*,*,認識,ニンシキ,ニンシキ
動詞,自立,*,*,サ変・スル,未然レル接続,する,サ,サ
動詞,接尾,*,*,一段,未然形,れる,レ,レ
ない 助動詞,*,*,*,特殊・ナイ,基本形,ない,ナイ,ナイ
名詞,非自立,一般,*,*,*,ん,ン,ン
じゃ 助詞,副助詞,*,*,*,*,じゃ,ジャ,ジャ

EOS




参考URL:
http://nshipster.com/nslinguistictagger/
http://d.hatena.ne.jp/shu223/20130318/1363566717

2015年4月12日日曜日

Google Code Jam-Qualification Round 2015

昨日、行われていたので、とりあえず飛び入り参加しました!
Google Code Jam-Qualification Round 2015

ルール

  • 問題は全部で四問ある。4問それぞれにSmallデータセット、Largeデータセットの2つがあり、それぞれに配点がある。満点は100。
  • 同じ点数なら、最初に提出してからの時間+ペナルティ時間が短いほうの勝利。
  • 27時間の間にとくプログラムを作成する。
  • 各問題について、まずSmallのデータセットをダウンロードして、3分以内にそのデータセットに対する回答と、とくのに使ったプログラムを提出する。"InCorrect"に対しては4分のペナルティが課される。回答が"Rejected"(形式が違う)された場合は、再度提出できる。それ以外の場合、再提出はできない。
  • Smallのデータセットに対して"Correct"判定をもらうと、Largeのデータセットにチャレンジすることができる。チャンスは1回のみ、ダウンロードしてから8分以内に回答を提出できなければ"InCorrect"となる。ただし、8分の間は何度でも提出し直すことができるが、最後に提出したもののみ採点対象となる。得点は一時的に追加されるが、コンテスト終了後に採点される。
  • 20点以上獲得すればQualification Round突破

僕は、A-SL, B-SL, C-Sだけ解けました
C-Lも解けたのですが、対応に間に合わず、8分の間には提出できませんでした・・・

D問題、たまたま先日悩んで諦めた課題だったので、諦めました
代わりに(?)、こんなリンクを貼っておきます


以下、僕の回答です。

A問題:Standing Ovation

#coding:utf-8

fr=open("A-large.in","r")

output=""
ans=[]
casenum=0

count=0
for line in fr:
    if count==0:
        casenum=int(line)
    else:
        tmp=line.split()
        Smax=int(tmp[0])
        sumnum=0
        level=0
        tmpans=0
        for a in list(tmp[1]):
            number=int(a)
            lack=level-sumnum
            if lack <= 0:#ok
                sumnum=sumnum+number
            else:
                tmpans=tmpans+lack
                sumnum=sumnum+number+lack
            level=level+1
        ans.append(tmpans)
    count=count+1



for i in range(0,casenum):
    output=output+"Case #"+str(i+1)+": "+str(ans[i])+"\n"

fr.close()


fw=open("out.txt","w")
fw.write(output)
fw.close()




  • 前から順にシミュレーションして、足りない場合は不足としてカウントしました。

  • B問題:Infinite House of Pancakes

    #coding:utf-8
    
    #D人の客が、それぞれPi枚のパンケーキを持っている
    #他の客は何もない
    #一分に一枚食べる
    #specialtimeは誰も食べない、パンケーキ有りの客からその他の客へパンケーキが移る
    #できるだけ早くパンケーキをなくす
    
    
    #kに展開した時のかかる時間数
    simulate=lambda pan,k :sum([int((i-1)/k) for i in pan])+k
    
    fr=open("B-large.in","r")
    
    output=""
    ans=[]
    casenum=0
    
    count=0
    for line in fr:
        if count==0:
            casenum=int(line)
        else:
            if (count%2) == 0:#list
                tmpans=10000
                diners=list(map(int,line.split()))
                for i in range(1,max(diners)+1):
                    tmp=simulate(diners,i)
                    if tmpans>tmp:
                        tmpans=tmp
                ans.append(tmpans)
        count=count+1
    
    
    for i in range(0,casenum):
        output=output+"Case #"+str(i+1)+": "+str(ans[i])+"\n"
    
    fr.close()
    
    
    fw=open("out.txt","w")
    fw.write(output)
    fw.close()
    





  • まず気づかなければならないのは、できるだけ早く分散させておいたほうがいいこと。
  • kこづつに分散させるのに、どのkが最適かわからなかったので、各kに対して回数を計算し、最小のものを選択しました。これでも時間的には大丈夫です。

  • C問題:Dijkstra

    #coding:utf-8
    #四元数
    
    
    def multi(b,a):#a*b
        dic={"11":"1", "1i":"i", "1j":"j", "1k":"k","i1":"i", "ii":"-1","ij":"-k", "ik":"j","j1":"j", "ji":"k", "jj":"-1", "jk":"-i","k1":"k", "ki":"-j", "kj":"i", "kk":"-1"}
        sign=["","-"]
        signflag=0
        if a[0]=="-":
            signflag=signflag+1
            a=a[1]
        if b[0]=="-":
            signflag=signflag+1
            b=b[1]
        res=dic[a+b]
        if res[0]=="-":
            signflag=signflag+1
            res=res[1]
        return sign[signflag%2] + res
    
    def convert(tmpstring):
        tmpc=tmpstring[0]
        for c in tmpstring[1:]:
            tmpc=multi(tmpc,c)
        return tmpc
    
    def main():
        fr=open("C-large.in","r")
        output=""
        ans=[]
        casenum=0
        count=0
        for line in fr:
            if count==0:
                casenum=int(line)
            else:
                if (count%2) == 1:#繰り返し回数
                    repeatnum=int(line.split()[1])
                else:
                    print(len(ans))
                    tmpans=False
                    stringdata=line.replace("\n","")
                    rank=0
                    tmp="1"
                    converted=convert(stringdata)
                    for j in range(0,repeatnum):
                        #あとは残りがkであることを示すのみ
                        if rank == 2:
                            for fds in range(0,((repeatnum-j)%4)):
                                tmp=multi(tmp,converted)
                            break
                        #i,jすら見つからないのであきらめ
                        elif j>=9:
                           break
                        #とりまi,jを探しに行く
                        else:
                            for c in stringdata[0:]:
                                tmp=multi(tmp,c)
                                #ひとまずiを見つける、あればjを探す、
                                if rank==0:
                                    if tmp=="i":
                                        tmp="1"
                                        rank=1
                                elif rank==1:
                                    if tmp=="j":
                                        tmp="1"
                                        rank=2
    
                    if rank==2 and tmp=="k":
                        tmpans=True
    
                    if tmpans:
                        ans.append("YES")
                    else:
                        ans.append("NO")
            count=count+1
    
        for i in range(0,casenum):
            output=output+"Case #"+str(i+1)+": "+str(ans[i])+"\n"
    
        fr.close()
    
    
        fw=open("out.txt","w")
        fw.write(output)
        fw.close()
    
    main()
    • まず気づかなければならないのは、"1"と等価な部分は右に含めても左に含めてもいいこと。つまり、"ijk"と等価なら、"i111jk"と等価なとき、当然"i11jk"、"i1jk","ijk"と等価なので、左から順にiを見つけ、jを見つけ、残りがkであればよい。
    •  large突破のポイントはループ対策。1111もiiiiもkkkkもjjjjも、すべて"1"と等価。より、n回同じものをかける場合は、n%4回かけるだけでよい
    • Cython使おうとしましたがあまり変わりませんでした。

    以上です。

    2015年3月11日水曜日

    Node.jsをインストールしようとしたらmakeに失敗した+bleacon

    Node.jsをインストールしようと思い、調べてみると、nodebrewというのをつかってバージョン管理するといいらしい。というわけで、試してみました。

    brew install nodebrew
    
    

    次に

    nodebrew install latest
    
    

    これでいけるはずが、

    fetch: http://nodejs.org/dist/v0.12.0/node-v0.12.0.tar.gz
    ######################################################################## 100.0%
    
      File "./configure", line 362
    
    
    
        '''
          ^
    
    
    
    エラーですね。進みません。

    試しに
    cd /.nodebrew/src/v0.12.0/node-v0.12.0
    make
    

    を実行するも、エラーばかり。

    ダメ元でconfigureを開いてみると、なんとpythonのコード!エラーのでている362行目を見に行く。

    print """〜〜〜〜〜""""
    

    なるほど。

    こういう部分すべてをprint("""〜〜""")になおしてもいけると思いますが、
    pyenv global 2.7.9
    にしてから

    nodebrew install latest
    
    
    を再度実行
    大量の文字が流れ、成功しました。

    後はパスを設定。

    cd
    vi .bashrc
    
    から
    export PATH="$HOME/.nodebrew/current/bin:$PATH"
    
    を最終行に追加して保存

    ターミナルを再起動して、
    node -v

    バージョンが表示されればOKです。

    npmコマンドも自動的に使えるようになっていますので、

    npm install bleacon
    

    みたいなこともできます。
    (このコマンドも、Python3でやるとエラーの山になります!Python2で実行してください!)

    nodebrewの詳しい使い方については→tavamy.blog-node.js 入れるなら nodebrew が超簡単

    2015年3月4日水曜日

    初めてMacを購入したDeveloperがすること

    0. はじめに

    プログラミングの言語は色々あります。Macは、購入した時点でPHPやRuby, Perl, Pythonのコマンドは入っており、開発可能です。以下、C, C++, Objective-C, Python, PHPの開発について、環境の構築について書きます。
    ブラウザからダウンロードしても使えるのですが、あとあとバージョン管理とかでちょっと困ると思うので。
    5までは全員すべきことで、それ以降はOptionalです。

    1. Xcodeのインストール

    まずはXcodeをインストールしましょう。Appleで開発者登録をすると、ダウンロードできます。iPhone/Mac開発には必須のツールです。また、他の言語の開発にも使える統合開発環境(IDE)です。
    Xcode

    2. Command Line Tools for Xcode

    次にCommand Line Tools for Xcodeをインストールします。
    xcode-select --install
    
    もしくは
    Downloads for Apple Developers(要ログイン)
    からダウンロード&インストールします。

    ここまでで、C, C++, Objectice-C, Swift(Mac, iPhone)の開発環境は整っています。iPhoneはエミュレータもついてきます。
    iPhoneの実機で実行するためのiOS Developer Programについては
    はるふ's Innovation!!ーiOS Developer Programへの参加
    をご参照ください。

    3. Javaのインストール

    Homebrewをインストールしたいのですが、その前に、Javaを入れる必要がある?(どちらかわからない)

    Androidの開発にも必須です。

    java -version
    
    を実行したとき、インストールされていたらバージョンが、されていなければインストールするかきかれる(らしい)です。

    インストールされてないのに聞かれなければ、
    Oracle-JavaからJDKのMac OS Xをダウンロード&インストールします。

    参考→QiitaーMacでJDKのバージョンを切り替える

    4. Homebrewのインストール

    インストールパッケージ管理に利用します。色々ブラウザからダウンロードするとバージョン管理が大変だったり、./configure;make;でエラーがでたらどうしようもなかったりと、homebrewを使うと便利です。

    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    
    これを実行
    これにより、brewコマンドが使えるようになります
    まずは指示に従い、
    brew doctor
    
    特に問題なければ、完了です。

    基本のbrewコマンドは、

    Homebrewのアップデート&再ビルド
    brew update
    brew upgrade
    

    パッケージ名(formula)を検索
    brew search (キーワード)
    

    パッケージのインストール
    brew install (パッケージ名)

    パッケージのアンインストール
    brew remove wget

    インストールされたパッケージ一覧を表示
    brew list

    です。
    ※Homebrew派とMacPorts派といて、Homebrew派の方が多いイメージがあります。ただ、共に入れるのはよくないようです。

    参考→Qiitaーパッケージ管理システム Homebrew

    5. gitのインストール

    最近のプログラマはとりあえずみんあGitを使っています。

    brew install git
    これだけでOKです。
    gitの基本的なコマンドについては
    はるふ's Innovation!!: サルでも分かるgit入門がわからない

    6. お好みのエディタ

    vimやemacsといったgeekなエディタは標準搭載しています。 Xcodeでの開発ならXcodeで開発できます。
    その他で有名なのは、Sublime Text
    やAtom
    です。
    お好みに合わせて。
    ※Sublime Textは無料で”つかう”ことができるのは事実ですが、長期利用は、有料です。

    7. Pythonの開発

    Pythonのバージョン管理ツールとして、Pyenvがよく使われます。
    brew install pyenv
    でインストール。 その後、
    pyenv install -l
    でインストール可能なパッケージ一覧が表示されます。

    自然言語処理や科学計算などを行う場合は、anacondaをインストールすると、その他様々なモジュールを同時にインストールできて便利です。

    2.7.9や3.4.3、anaconda-2.1.0やanaconda3-2.1.0など、
    pyenv install 2.7.9
    みたいな感じで、一覧の時に表示された時の名前を使ってインストールします。

    Python 2.xとPython 3.xでわりと差があるので、どちらを使うかは、場合によります。そのため、anacondaもanaconda(2.x系)とanaconda3(3.x系)で分かれています。Pyenvを使っているなら、どっちもいれて、切り替えても問題無いです。
    参考→Python 2 と Python 3 のどちらを使って開発すべき?

    anacondaについて、詳細は以下のリンクをご参照ください
    参考→QiitaーMacでPython3系ベースの機械学習環境設定(Python2系との共存)

    以降は引数なしでpythonなら対話モードで、python (ファイル名.py)ならばそのファイルが実行されます。

    pythonのモジュールの追加は、pipから行います。
    はるふ's Innovation!!ーTweepy+Pythonによるユーザーストリーム〜pip, tweepyのインストールから〜(Mac)
    を参照してください。
    pip list
    でインストールしたモジュール一覧を見ることができます。

    Mecabを使う場合は、
    brew install mecab
    brew install mecab-ipadic
    でmecabを入れます。これでコマンドからmecabを使えるようになります。

    pythonから使えるようにするには、
    pip install mecab-python
    を実行します(python3なら右をpython3にする)
    これで、pythonからimport Mecabを実行できます。

    8. PHPの開発(Apache, FileZilla)

    PHPはサーバーで処理を実行し、するので、デバッグにはサーバーが必要ですが、いちいち送るのはとても面倒です。そのため、PC上に仮想的にサーバー環境を構築すると便利です。
    Apache(仮想のサーバー)はもともとインストールされています。
    sudo apachectl start
    により、Apacheを起動。startの部分をstop, restartにすると、停止, 再起動を行うことができます。起動している状態で、ブラウザに
    http://localhost
    を入力すると、
    It Works!
    が表示されます。表示されれば、起動しています。

    ApacheでPHPを有効にするには、httpd.confというファイルを編集する必要があります。
    vimエディタを用います。ちょっと扱いが難しいので、リンクをご参照ください→vimコマンド一覧

    sudo vi /private/etc/apache2/httpd.conf
    でvimが起動したら、i(挿入モードへ)
    #LoadModule php5_module libexec/apache2/libphp5.so
    を探して、先頭の#をとる
    そのご、EscまたはCtrl+C(コマンドモードへ)
    :wqを入力してEnter
    PHPのバージョン管理をする場合は→PHP利用のための設定

    以上で設定は完了です。

    http://localhostは
    /Library/WebServer/Documentsの中身を示します。つまり、ここのindex.htmlが読まれているので、ここに例えばsample.phpみたいなファイルを置いて、http://localhost/sample.php
    にアクセスすると、PHPのサーバーの実行結果を見ることができます。

    PHPのエディタには、僕はSublimeを使っています。

    サーバーをかりているとき、サーバーにファイル送るときは、FileZillaを用います。

    cakePHPはフレームワークの一つです。僕は使ったことがないので、調べてみてください。

    ※PHPで開発する際、いわゆるたとえば$が抜けている、のようなミスの時、何も表示されなくて困ります。そういう時はphpコマンドを実行すると、pythonの実行時みたいにエラー検出できます。

    9. Androidの開発

    Androidの開発は、これからの時代は、Eclipseではなく、Android Studioを使うべきです。(SDKは廃止予定とのことです)
    参考:第 3 回・新 IDE : Android Studio を使ってみよう!
    参考:【ADB】Java(JDK)とAndroid SDKを導入してADBコマンドを使えるようにする

    公式のエミュレータはとても重いので、変える必要があります。公式以外のエミュレータとしてGenymobileなどを使うのもひとつの手ですが、公式も、intelのHAXMを使うと、早くなります→参考:Android SDK の高速エミュレータ、使ってますか?

    Androidアプリのファイル構成は
    QiitaーHello worldで分解するAndroid Studioのプロジェクトの内容
    がわかりやすいです。

    10. Unityの開発

    インストールしましょう。


    以上がやったことのある開発環境の準備です!

    2015年3月3日火曜日

    はじめてのWebAPI〜基礎とSwiftでの実装〜

    APIとは、あるデータや機能を、他のプログラム(外部)から呼び出すためのインターフェースの仕様を示します。
    そのうち、Web上にあるプログラムを用いるものがWeb APIです。

    APIを用いることで、到底一人のプログラマには集められないようなデータを使えたり、機能を使えたりします。
    APIとしては本当に色々あり、TwitterAPIやHOT PEPPER API、Google Maps API、Yahoo!のAPIなど、各社が様々なAPIを提供しています。
    参考:ライブラリ・フレームワーク・APIの違い

    APIを使う側についての記事です。

    まず、身近な例として、普段見ているwebサイトについて。このブログの場合、
    アドレス”http://ha1f-blog.blogspot.jp/”を入力すると、そのアドレスにあるサーバーに対し、HTTPリクエスト(ページの要求)が送信されます。それに対し、サーバーが応答し、HTTPレスポンスとして、ページの内容や画像を返します。
    参考:IPアドレスとは
    参考:Webサイト高速化に必要なHTTPの仕組みを理解する


    そして、送られてくるデータは文字がずらずら並んだデータです。つまり、右クリックから「ページのソースを表示」をしたときに表示されるもの

    こんな感じで見れます。(このブログでの例、HTML形式で記述されています)
    これがこのブログの正体?です。このデータをブラウザが解析して、キレイに表示しています。

    大体見れたかと思いますが、ネットからデータを取ってくる際に、データを取ってくるのが第一の課題、取ってきたデータをどう処理するか(パース)が第二の課題になります。


    今回はRECRUIT Webサービスの一つ、HOT PEPPERのグルメサーチAPIを例に取ります。
    ここから利用規約を読んで、登録すると、APIキーを発行することができます。

    以降、keyは****************として表記しますが、自分で取得したキーを入れてください。

    <第一の課題>
    とりあえず
    http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=****************&format=json&lat=35.6800079345703&lng=139.768936157227
    をブラウザに入力してみると、

    こんな感じのデータが見れるかと思います。(今回はJSON形式のデータです)
    ブラウザを使うと、データを取ってくるのは簡単ですね。

    これをiPhone(Swift)で実現するには

    // use NSURLSession
            var url: NSURL = NSURL(string:"http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=****************&format=json&lat=35.6800079345703&lng=139.768936157227")!
            var myRequest = NSMutableURLRequest(URL:  url)
            myRequest.HTTPMethod = "GET" 
            var task = NSURLSession.sharedSession().dataTaskWithRequest(myRequest, completionHandler: { data, response, error in
                if (error == nil) {
                    //正常終了、レスポンスはdataに
                    println(NSString(data:data, encoding:NSUTF8StringEncoding))
                    }
                } else {
                    println(error)
                }
            })
            task.resume()
    

    このように記述します。

    NSURLSessionを用いています。

    NSURLConnectionは色々な通信を行うことができますが、http通信であれば、簡略化したクラスNSURLSessionを用いたほうが、楽に非同期通信を実現できます。
    ※非同期通信→並列処理。データを取ってくるのに時間がかかることが多いため、その分プログラムの動作を停止するのはもったいない。よって、バックグラウンドでも実行できるようにこの方式を使うことが多い。
    参考:非同期通信

    NSURL()によって文字で書かれたurlをurlの形式にエンコード

    HTTPリクエストの形式は"GET"(受信)と"POST"(送信)の2つがありますが、今回はデータをPOSTする必要はないので、"GET"にします。これをNSMutableURLRequestの.HTTPMethodメソッドによって、行います。

    そして、NSURLSession.sharedSession().dataTaskWithRequestによってタスクを生成し、task.resume()でそのタスクを開始しています。
    つまり、生成されたtaskの中の命令が、task.resume以降にバックグラウンドで実行され始めます。

    これで第一の課題終了です!と行きたいところですが、肝心のURL部分について説明していません。笑
    URLはAPIリファレンスを見ながら考えます。

    今回使ったURLは、
    http://webservice.recruit.co.jp/hotpepper/gourmet/v1/
    ?
    key=****************
    &
    format=json
    &
    lat=35.6800079345703
    &
    lng=139.768936157227
    と分解することができます。
    これで、JSON形式で緯度経度が(35.6800079345703, 139.768936157227)周辺の店データを取得できます。

    一つ目はアドレスで、?以降は引数のようなものになります。(引数名)=(内容)として、&でつないでいきます。どんな引数があるかは、リファレンスに示されています。

    まずリクルートのAPIを使う場合は、key=****************が必須です。
    formatは、標準はxmlとなっていますが、Swiftの場合はJSONのほうが扱いやすいので、JSONにしています。
    lat=?とlng=?で緯度経度を指定しています。
    他にも色々試してみましょう!

    日本語を入れたい場合は、
            let query: String = textinput.text
            let encodedQuery: String = query.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
            var urlstring = "http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=****************&format=json&name=\(encodedQuery)"
    こんな感じで、文字をエンコードしてから入れる必要があります。アドレスバーでよく見る%xx%xx%xxみたいな形式に変換されます。

    これで本当に第一の課題完了です!


    <第二の課題>
    上のプログラムで、「//正常終了、レスポンスはdataに」の部分に、正常にデータを取得できた時の命令を足していきましょう。

    まず取得したデータをそのまま見ると、(ブラウザの場合の画像参照)まあわけわからんぐらい長いデータが続いています。これをSwiftで解析するときには、SwiftyJSONが便利です。
    SwiftyJSONはGitHubに公開されているので、こちらから利用させて頂きます。ここから、Source/SwiftyJSON.swiftをダウンロードして、プロジェクトフォルダ内にいれ、Drag&Dropでプロジェクト内に入れておきます。
    これだけで使用準備は完了です。

    あとは正常終了時のコードとして、
                    let json = JSON(data: data)
                    for i in 0...9{
                        if let stringdata = json["results"]["shop"][i]["name"].string{
                            NSLog(stringdata)
                        }
                    }
    を追加します。これでshopの名前が10個、出力されます。

    一番上の行だけでJSONを解析してくれるので、あとはリファレンスを参照しながら、取り出したいデータを見ていきます。基本は[]の内部の値(辞書のキー)を変えるだけでOKです。(ブラウザで取得されたデータを見てもわかりやすいかもしれません)

    標準では10件の店データが取得されるので、i=0〜9のデータを見ています。

    web上の画像からUIImageを生成したい場合は、
                            let imgurl = NSURL(string: json["results"]["shop"][i]["logo_image"].string!)
                            var err: NSError?
                            var imageData :NSData = NSData(contentsOfURL: imgurl!,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)!;
                            var img = UIImage(data:imageData)!
    
    このようにします。

    第二の課題は、SwiftyJSONのお陰で、とても簡単に解決出来ましたね!

    本記事は以上です!

    2015年2月26日木曜日

    サルでも分かるgit入門がわからない

    有名サイト、サルでも分かるGit入門

    これ、なんか微妙にわかりにくい!というわけで、まとめます!

    Xcodeについてと、コマンドについて!絡めながら行きます。Xcodeのgitは直感的で楽ですが、エラーに対処しにくいので、2つあったほうがいいかと思います。

    git cloneとかはおいといて、とりあえず、pushすることを考えて、pushできるように、書きます。内容的には不十分ですが、とりあえずpushできるようになることを目標に・・・


    <用語説明>
    リポジトリ=履歴を管理する、プロジェクトのうち変化する部分

    ブランチ=枝。とりあえずmasterしか考えなくてよい!mergeとかはおいておこう!

    ワークツリー=ローカルでの作業ファイル全体

    ローカルリポジトリ=PCにあるリポジトリ
    リモートリポジトリ=サーバー上にあるリポジトリ。GitHubが有名。

    コミット=コメントとともに、インデックスに追加されたファイルの変更履歴を保存します。(ここまではローカルで実行できる)

    インデックス=gitの監視下したいファイル群

    プッシュ=リモートリポジトリに今までのコミットをすべて送信すること(同期みたいな)
    プル=リモートリポジトリからコミット内容をダウンロードすること

    <gitの目的>
    まず、ファイルの変更履歴を管理できます。どこを書き換えて動かなくなったのか、みたいなことを調べることができます。

    また、複数人で同じプロジェクトについて作業するのに使います。

    ローカルリポジトリは適宜コミットし、いざというときにプッシュします。プッシュすると、ローカルで溜まっていたコミット履歴が一気にリモートリポジトリへ送られます。

    最近はそれだけでなく、自分の能力のアピールにも、つまり、今までどんなプログラムを書いてきたかの紹介に使われていることが多い気がします。

    とりあえず、リモートにファイルを置くときの大まかな流れは、
    空のリモートリポジトリ作成する
    ローカルでリポジトリ作成する→リモートリポジトリを登録する。
    →ファイルをインデックスに追加→コミット→↓→プッシュ→↓
    ↑←←←←←←←←←←←←←←←←←←←←←←←←←←←←

    です!


    <ローカルでのGitリポジトリ〜Xcodeを絡めながら〜>
    gitリポジトリを作成するコマンドは、
    git init
    
    です。
    Xcode 6以降で新規プロジェクトを作成し、ファイルの保存場所を指定するとき、"Create git repository on MyMac"にチェックを入れておくと、自動的にgitのrepositoryを作成してくれます。


    次に、XcodeのSource Control→Commitを押した時の画面について!
    git add file.swift
    
    これでfile.swiftというファイルがインデックスに登録されます。つまり、次のCommitからは、gitの監視下に含まれるようになります。複数ファイルを追加したい場合、
    git add file.swift file2.swift file3.swift
    
    のようにかけます。これはXcodeでいうチェックを入れる操作に当たります。
    そして
    git commit
    
    これでコミット!変更履歴がgit repositoryに保存されます。

    git add -u
    git commit
    
    上のコマンドは、直前のコミットから変更があったファイルをaddする命令です。コミットに必要なファイルが追加されていない場合、こればかり実行していればよいです。

    Xcodeでも、ここまではCommitボタン押すだけなので、難なくクリアできます。

    ※Commitの時に、必ずメッセージを添える必要があります。Xcodeでれば、下のボックスに入れます。コマンドからの時は、vimが起動するので、iでinsertモードに→適当に入力→Escでコマンドモード→:wq(保存して終了のコマンド)を入力してEnter、これでOKです。

    補足
    git rm file.swift
    
    ファイルを削除するとき、普通に削除だけすると、gitの監視下に置かれたファイルがないという状況になり、よくないです。そこで、git rmコマンドが存在します。これを使うと、rmoveすることができます。後ろに--cachedオプションをつけると、ファイルを残したまま、インデックスからのみ削除することができます。
    git mvコマンドも同様に使うことができます。



    <Remoteにも拡張しよう>
    まずは、GitHubのアカウントを取りましょう!特に苦労せず取れます!

    リモートリポジトリを作成するときは、GitHubのサイト上で作成します。
    作成した後は、何もさわらないでおきます。SSHの方のURLをコピーしておきます。

    これに対して、
    git remote add origin git@github.com:***/*****.git
    
    を実行します。後ろの部分は先ほどコピーしたURLを使います。
    これで、remoteリポジトリとして上のアドレスに示されるリポジトリが登録されます。
    Xcodeの場合は、Source Control→(ファイル名)-master→Configure (ファイル名)
    からRemotesを選び、左下の+ボタンから追加する操作に当たります。
    ここでのoriginは名前なので、なんでもいいです。

    git remote
    
    これでリモートリポジトリに登録されたものの一覧を取得できます。Xcodeの先ほどのRemotesの画面と同様です。

    最後は
    git pull origin master
    
    でプッシュ

    エラーがなければ、Gitのページを見に行ってみましょう!ファイルが入ってれば成功です!

    ※先にリポジトリを編集していると、pushの時にこういうエラーが出ます。
     ! [rejected]        master -> master (non-fast-forward)
    error: failed to push some refs to 'git@github.com:***/****.git'
    hint: Updates were rejected because the tip of your current branch is behind
    hint: its remote counterpart. Integrate the remote changes (e.g.
    hint: 'git pull ...') before pushing again.
    hint: See the 'Note about fast-forwards' in 'git push --help' for details.
    

    もしくは、
    Working copy out of date.
    
    (別の方法/人からのプッシュがあったために、競合が発生している状態です)

    この場合、競合を解決する必要があります。そのため、まずプル。そしてマージ(プログラムを合わせる)
    git pull origin master
    
    を実行します。これで、リモートリポジトリoriginのmasterブランチをプルできます。
    競合のあった場合は、慎重にマージしましょう。自分一人しか変更してない場合は、たいてい気にしなくて大丈夫です
    その後pushすれば問題なく成功するかと思います。

    画像がなすぎるのであとで追加します・・・

    少しはわかるでしょうか・・・

    ちなみに、僕のGitHubのアカウントです。
    https://github.com/ha1fha1f
    大したコード上げてないというか、混沌としていますが、もっと整理して、たまにはコード上げたいと思っています
    (APIキーなどをいちいち消したファイルをつくるのが億劫で、上げないことが多い……)

    2015年2月14日土曜日

    Tweepy+Pythonによるユーザーストリーム〜pip, tweepyのインストールから〜(Mac)

    Tweepy+PythonによるTwitterのStream

    REST APIStreaming APIがあります。
    REST APIは取得回数に制限があり、リアルタイムに更新するような動作はできません。そこで、Streaming APIを用いると、The WorldやYorufukurouみたいに、制限をあまりきにすることもなくリアルタイムにツイートを取得できます。

    REST APIについては、
    Qiitaー「Python で Twitter API にアクセス」
    こちらのサイトがとてもわかり易いです。
    ツイートの投稿検索タイムライン取得などの操作ができます。

    以下、Streaming APIについて。

    まず、インストールから。
    Tweepyを入れようとしたら、
    ImportError: No module named pip.req
    と言われ、何のことかと思えば、pipを入れてないからですね

    ターミナルで
    curl -kL https://raw.github.com/pypa/pip/master/contrib/get-pip.py | sudo python
    
    これでpipがインストールできます。
    こちらを参考にしました)

    よって、
    easy_install tweepy
    これが実行できるようになり、tweepyがインストールできます
    sudo pip install tweepy
    でもよいです。

    そしてtweepyでの開発へ。
    を参考にしました。特にデータの表示部分、日本時間への変換、エラー対処です。

    Public Streamingのコマンドは
    が参考にになります

    *ユーザーストリーム
    # coding: utf-8
    #はるふ's innovation!
    import tweepy
    from datetime import timedelta
    
    CK = ''                             # Consumer Key
    CS = ''         # Consumer Secret
    AT = '' # Access Token
    AS = ''         # Accesss Token Secert
    
    class Listener(tweepy.StreamListener):
        def on_status(self, status):
            status.created_at += timedelta(hours=9)#世界標準時から日本時間に
            
            print('------------------------------')
            print(status.text)
            print(u"{name}({screen}) {created} via {src}\n".format(
                                                                   name=status.author.name, screen=status.author.screen_name,
                                                                   created=status.created_at, src=status.source))
            return True
        
        def on_error(self, status_code):
            print('Got an error with status code: ' + str(status_code))
            return True
        
        def on_timeout(self):
            print('Timeout...')
            return True
    
    # Twitterオブジェクトの生成
    auth = tweepy.OAuthHandler(CK, CS)
    auth.set_access_token(AT, AS)
    
    listener = Listener()
    stream = tweepy.Stream(auth, listener)
    stream.userstream()
    

    表示部分はめじろさんのコードほとんどそのままです…
    return Trueをすると、timeoutが発生しても終了しなくなります

    * 検索ワードをストリームで流す(Public Streaming)
    stream.filter(track=['検索ワード'])
    
    最後のstream.userstream()をこれに書き換えるだけです

    ただし、こちらを参照してください。
    Kimux.Netー「[Python]twitterのstreaming APIは日本語によるフィルタリングが未対応。」
    調べたところ、完全に未対応というわけではありませんが、単語がスペースなどで独立している場合は検索可能なようです。よって、ハッシュタグや英単語は検索できそうですが、日本語の文章の内部の検索は無理そうです(REST APIを使うしか・・・)

    同じ部分を、
    stream.sample()
    
    とすると、全世界のツイートの断片が拾われ続けます。すごいスピードで流れて、ある意味楽しいです


    ちなみに、ストリームを終了するときはControl + Cで割り込みを発生させると終了させることができます(正しいかどうかはわからない)


    2015年2月13日金曜日

    PHPでのTwitterOAuth

    PHPでのTwitterOAuthについて、ネットを見ていると変な記事ばかりなので、少しまとめます。(もしかしたら仕様が変わっただけかもしれません)


    ここでは、Consumer Key(API Key), Consumer Secret, Access Token, Access Token Secretの取得方法については、省略します。

    Twitterを使ったアプリケーションを作るときにさけて通れないのが、OAuth認証です。この部分について、PHP用にライブラリを作った方がいます。

    それをGitHubにアップロードされているので、
    GitHub - abraham/twitteroauth
    こちらを利用させていただきます。右端のDownload-zipからダウンロードできます。

    これがまるでTwitter APIそのものであるかのような説明がなされているブログが散見されますが、OAuth認証はTwitter以外でも使われている認証方法であり、OAuth認証の部分とTwitter APIとのあたりをabrahamさんがライブラリ化して、出来上がったのがこれです。

    GitHubの中身をよく見ると、ドキュメントをここで公開されているので、概ねこの方法に従った方法を、簡単に説明します。

    まずsample.phpと同じフォルダに、"autoload.php"および"src"フォルダを中身ごと、保存しておきます。
    そして、"sample.php"の中身は
      <?php
    //はるふ's innovation!
      require_once(dirname(__FILE__)."/autoload.php");
      use Abraham\TwitterOAuth\TwitterOAuth;
    
      $consumer_key = "";// Consumer keyの値
      $consumer_secret = "";// Consumer secretの値
      $access_token = "";// Access Tokenの値
      $access_token_secret = "";// Access Token Secretの値
    
      // OAuthオブジェクト生成
      $twiter = new TwitterOAuth($consumer_key,$consumer_secret,$access_token,$access_token_secret);
    
      $user = '_ha1f';
    
      $tweets = $twitter->get('statuses/user_timeline', array('screen_name' => $user));
    
      foreach ($tweets as $i => $tweet) {
        echo "$i: $tweet->text" . PHP_EOL;
      }
    
    こうします。もちろん、4つのキーはすべて値を入れておいてください。(文字列として)

    require_once(dirname(__FILE__)."/autoload.php");
    で同じフォルダにある"autoload.php"をrequireしています。

    これで僕のTLが表示されるかと思います。一部ファイルのみをコピーしてOAuth部分だけ利用する方法が紹介されているブログもありますが、おそらくこれが作者の意向にあった使い方かと思います。

    ちなみにget関数に渡しているURLは、URLから前の部分
    "https://api.twitter.com/1.1/"と、最後の".json"を省いたものです。
    つまり、検索結果をgetしたいときには、
    $timeline = $twitter->get('search/tweets', array('count' => '100', 'lang' => 'ja', 'q' => 'はるふ exclude:replies exclude:retweets'));
    $tweets = $timeline->statuses;
    とすればよいです。

    2015年2月12日木曜日

    文字列の分割(.split())について

    PythonやSwiftでの文字列操作ですごく便利なのが
    .split()
    です。

    引数を省略した場合は' '(スペース)で区切られるかと思います。しかし、web上のファイルは'\t'(タブ)で区切られていることが多いです。CSVファイルであれば','で読みます。

    ここで、複数の種類の文字で分割するにはどうすればよいか。

    解決法は、2つあります。ひとつは正規表現(reモジュール)を使うこと、もうひとつは、文字列を先に.replace()しておくことです。分割しようと思ってる部分なので、問題はないはずです。

    正規表現は便利ですが、忙しい時などは、後者の方法のほうが手軽に書けます。前者のドキュメントはどこにでもあるので、後者について書きます。

    つまり、文字列変数stringをタブ、スペース、コンマの全てで区切りたいときは、
    string.replace('\t',' ')
    string.replace(',',' ')
    list = string.split()
    こうすればできます

    非常に簡単なので、よく使います・・・

    2015年2月9日月曜日

    階乗、組み合わせ、順列、絶対値

    プログラムでの階乗、組み合わせ、順列の求め方について。 階上はそのままですが、組み合わせや順列は公式通りに階乗から計算しようとすると、計算途中にオーバーフローする可能性が高くなり、あまり好ましくないです。そのため、漸化式を用いて記述することが多いです。以下Cでのサンプルコード。
    long kai(int n){//nの階乗
        long p=1;
        int i;
        for(i=2;i<=n;i++){
            p=p*i;
        }
        return p;
    }
    
    long pof(int n, int r){//nのr乗
        int i;
        long p=1;
        
        for (i=0 ; i < r ; i++){
            p=p*n;
        }
        return p;
    }
    
    long combi(int n, int r){//nCr
        int i;
        long p=1;
        
        for (i=1;i <= r;i++){
            p=p*(n-i+1)/i;
        }
        return p;
    }
    
    long perm(int n, int r){//nPr
        int i;
        long p=1;
        
        for (i=1;i<=r;i++){
            p=p*(n-i+1);
        }
        return p;
    }
    
    再帰関数を使っても実装できるかもしれませんが、こちらのほうがわかりやすいので。これより高速なコードは存在しますが、簡単なのを書きました。

    べき乗については、繰り返し2乗法というアルゴリズムが存在します。nのr乗を、n, nの2乗, 4乗, 8乗, ……に分解して高速化する方法です。



    ところで、絶対値について、絶対値を求める関数absは標準で用意されています。 普通人間が絶対値を計算したいとき、ifで場合分けして〜というコードを書きそうですが、実は、2進数のビット演算のみで、三行で構成されています。高速にできている… Cなどの言語はコンパイル作業によって最適化されます。DebugをReleaseにすると更に最適化されます。 アーキテクチャまで考えられたプログラムを書けるようになりたい・・・

    2015年2月8日日曜日

    Pythonの文字列の切り出し(スライス)について

    Pythonにおいては、
    string = 'abcdef'
    print string[0:2]
    
    のようにすると、0,1文字目(ab)を切り出す事ができます。よく使うのはこの形ですが、3つ目の引数(?)を指定することができます。

    string[i:j:k]
    であるとき、
    iは読み出し開始位置(含む)、
    jは読み出し終了位置(含まない)、
    kはステップ
    を意味します。

    ステップを負の数にすると、逆順の文字を作ることができます。また、iやjを負数にすると、右から何文字目かを表すことができます。
    よって、読み出されるのは i, i+k, i+2k, i+3k, …(< or > j)ということになります。 

    また、各パラメータ省略することができます。(string[::]ならそのまま)
     iを省略した場合は、左端(if ステップ>0)or右端(if ステップ<0)、左端の次(if ステップ<0)

    string = 'abcdef'
    print string[::]#そのまま(abcdef)
    print string[::-1]#逆順(fedcba)
    print string[:4]#左端から4文字目まで(abcd)
    print string[-3::-1]#右端から3文字目から左端まで逆順(dcba)
    

    あるプログラムの問題をといてる時にこんがらがったのでまとめました・・・

    2015年1月21日水曜日

    文字のエンコードについて〜Python with Xcode 6 補足〜

    先日の記事

    Xcode 6でPythonの開発を行う(Mac)

    の補足です。

    文字エンコードについて。
    ソースのエンコード、システムのエンコード、ファイル入出力のエンコードなどそれぞれありますが、たぶん、こんがらがらないためには、統一しておくのが一番かと思います。もちろん合わせなきゃいけない場面もあるでしょうが、自分で使う分には統一が一番ですよね!?
    Defaultは基本的にPython 3系では標準がUnicode形式になりましたが、Python2.x系ではUS-ASCIIになっており、日本語を入力できなかったり非常に不便ですので、変更方法などご紹介します。プログラムで処理することもできますが、コーディングしやすくなります。

    以下、Python2.x系に向けた記事です。

    <ソースコードのエンコード>
    Pythonでソースコードを書くときは、基本的に、1行目でエンコード形式を指定します。ASCIIでは、たとえコメントにでも日本語を入力したとき、そのままの設定ではエラーになってしまいます。

    僕の場合は、Xcodeの標準に合わせ、
    # coding: UTF-8
    にしました。Xcode側からも、右側のText Encodingから変更などできます。
    (vim形式、emacs形式など、表記法にも複数あるようです。大文字・小文字は区別されません。)
    これで、日本語も記述できるようになります。

    ただ、例えば文字列の長さを取得したいとき、len(u'日本語')=3ですが、len('日本語')は3ではありません。こういう点ではやはりunicodeが便利で、Python3系が羨ましくなります。また、どの文字コードがいいのかわかりません・・・

    <システムのエンコード>
    次に、デフォルトのエンコードについて。デフォルトでは、入出力もUS-ASCIIになっており、不便です。よって、これをUTF-8に書き換えたいところです。(ただ、設定の書き換えなので自己責任で!)

    方法は、sitecustomize.pyというファイルを作り、
    import sys
    sys.setdefaultencoding("utf-8")
    
    を入力して保存。
    Macintosh HD->ライブラリ->Python->2.7->site-packages->にファイルをコピーすれば完了です。
    確認は、Pythonを対話モードで起動して、
    import sys
    sys.getdefaultencoding()
    
    を実行すれば、defaultencodingを表示させることができます。utf-8になっていれば設定完了です。

    <ファイル入出力のエンコード>
    今回僕が躓いたのは、Excelで適当に出力したCSVファイルをMac上でのPythonで動かそうとした時です。CSVファイルは、表などを特定の文字で区切って保存する形式です。Pythonの標準モジュールCSVを使うと、簡単に読み込めます

    まず、プレビューで見ても、日本語に対し、文字化けが発生しました。これは、そのCSVファイルをテキストディットで開き、何もしないまま保存すると、なおります。
    見るだけならこれで十分ですが、これでは文字エンコードが何かわからなくて、プログラムで読むにはこまります。

    そこで、文字コード統一のメリットを活かして、文字化けしなくなったファイルをNumbersで開き、ファイル→書き出す→CSVから、テキストエンコーディングを「Unicode (UTF-8)」を選択し、書き出します。
    これで、そのまま読めるようになります。



    以上書いたのは、とても基本的なことですが、プログラム(encode, decode)で処理するよりも外部で処理したほうが簡単で、コーディングがとてもしやすくなりますよ!

    リストの中の文字列を表示する方法など、こちらで紹介されています→japaneseCharset

    2015年1月15日木曜日

    Xcode 6でPythonの開発を行う(Mac)



    Swiftを書いてから、統合環境Xcodeでの開発に慣れてしまい、vimやemacsが使えなくなりました・・・


    PythonもXcodeで開発するための方法を示します。ただし、Pythonのインストールについては省略します

    Pythonはインタープリター型の言語であるので、プログラムを逐次翻訳していきます。つまり、ほかの言語でいうコンパイルの操作が不要であることを意識しながら作業を進めましょう。

    satomacoto - 「Xcode 4でPythonの開発環境を整える」
    を参考にしました。
    画像を多く使い、わかりやすく解説してくださっています。

    pyファイルを実行するときには、
    $ python (ファイルパス).py
    を実行します

    つまり、Xcodeのビルドボタンを押した時にこのコマンドが実行されるようにすればよいです

    ファイルの作成は不要なtargetを削除して、Schemeの設定をしっかりすれば、Command Line ToolでもEmptyでもなんでもいいです。不安な方は上のリンクから参照してください。

    ここでは、Xcode4と6とで見た目が違う、Schemeの設定について書きます
    (僕の場合、プロジェクト名をpythontest、ファイル名はsource.pyにしました)


    上のメニューのProduct→Scheme→Edit SchemeからRunタブのInfoタブをひらき、設定を画像のようにします。
    "Executable"は"Other"を選択し、⇧⌘G (shift + command + g)で¥usr¥bin¥を入力して移動し、pythonを選択します。
    それと、"Debug Executable"のチェックを外します。

    終われば、Argumentsタブに移動します



    "Arguments Passed On Launch"の"+"から
    $(SOURCE_ROOT)/実行したいファイル名.py
    を入力します。これがつまりコマンドライン引数になります。別の場所に.pyをおいている場合はそちらを指定します。

    以上でSchemeの設定は完了です!



    あとはコードとして、

    print "hello world!"

    とでもかいて、実行してみましょう!




    ちゃんと実行できました!!

    ※2015/1/19追記
    標準入力が動作しないことがわかりました。原因究明中です。

    ※2015/1/21追記
    文字エンコードについて補足しました。コーディングしやすくなる方法です。
    →<http://ha1f-blog.blogspot.jp/2015/01/python-with-xcode-6.html>
    標準入出力については変化がありません。

    2015年1月6日火曜日

    HACK U 京都大学


    ずいぶんと前の事になりましたが、2014/12/20に、HACK U×京都大学というイベントに参加しました。
    京都大学 デザイン学大学院連携プログラム主催、ヤフー株式会社共催のハッカソンイベントです。

    Yahooで行われるハッカソンイベントHack Dayの大学生版で、2週間で作ることが課題でした。特に与えられたテーマなどもなく、「創作」であればOKでした

    そのイベントに向けて僕らが作ったアプリケーションがARound グルメです。

    自分の周囲にある店の情報と、Twitterで特定のハッシュタグ付き(アプリ内でつぶやける)でつぶやかれたレビューとを、カメラ画像の上にAR(拡張現実)として表示するiOS用アプリケーションです。
    経路案内機能、評価をサーバーに保存/平均をとって出力する機能、ツイート機能などもついてます。


    このイベントのために、僕はSwiftを、友人がSwift, PHP, データサーバを0からはじめ、なんとか完成しました。ソースコードはとっても汚いです

    そして、努力した甲斐があり、最優秀こそ取れなかったものの、「技術賞」を頂きました。栄誉あることです!


    最優秀はなんと高校のロボット部の先輩のチームで、研究室(松野研)のメンバーで出場していたそうです。二週間ですごいロボット作っていらっしゃいました・・・凄いです・・・

    ロボット部の先輩方は、僕より上には4年しかいないのですが、東大ロボコンチーム80人を率いるリーダーをしていた方、学部2回生から学術論文の投稿や学会発表をしていた方、SECCONで上位の方など、すごい方いっぱいいます・・・
    僕もすごいことしたいのに、どこまでなれるでしょうか(泣

    最後話が変わりましたが、とりあえずもっと色々頑張りたいです・・・!

    2014年12月25日木曜日

    CODE VS 4.0に参加したい初心者のための補足ドキュメント

    RECRUIT社主催の、CODE VS4.0というコンテストがあり、現在予選が開催されています。

    12/22〜1/31の間にあるゲームを実行するAIを組み、サンプルのAIと対戦します。そのランキングの上位8人が決勝へ進出できます。
    参加は社会人でも可能で、かなりレベルが高そうです。。。

    内容はとても面白そうで、だれもがやってみたいと思うんじゃないかと思います。参加方法およびクライアントのエラーについて、いくつか困った点があったので、対処を紹介します。
    ゲームのルールなどは、公式ページを参照してください。

    僕の環境はMac, Xcode 6, C言語です。

    エントリー後、クライアントをダウンロードできます。クライアントは自分のAI(実行ファイル)を指定すると、ゲームを実行するプログラムです。

    <CODE VSにつながらない>
    Google検索から飛ぶと、つながりません。http://をhttps://にするか、CODE VS 4.0のページからいろいろ移動するとつながります。

    <Xcode, クライアント操作>
    XcodeのNew Project → OSX → Command Line Tool
    コーディング後、ビルドすると、
    /Users/(ユーザー名)/Library/Developer/Xcode/DerivedData/(プロジェクト名)-(ハッシュタグ)/Build/Products/Debug/(プロジェクト名)
    に実行ファイルが保存されます。
    これをクライアントで読み込んで、実行させます。

    「ローカル実行」はいつでも実行できますが、チェックを外すと、一時間に一回しか実行できなくなります(ランキングに反映される)

    終わった時でも、Stopで中断した時でも、そこまでの履歴を「ローカル履歴」もしくは「履歴」で確認することができます(わりとかっこいい)

    <クライアントのエラー>
    「プロセスの起動に失敗しました」……ファイルのアドレスのエラーです。「ファイルを選ぶ」からファイルを選ぶと" "がつきますが、これもはずさないとこのエラーが出ます

    (実行しても何もでない)……おそらく、出力形式が間違っています。サンプルコードを見ながら、直してみてください。僕の場合、ID出力をinputの後にしていたためこれが起こりました。起動と同時にIDを標準出力しなければなりません。

    "You have not enough resources"……読んでそのまま、資源不足です。

    "L1:[(内容)]"……不正な入力です([ ]内部が内容)


    僕が把握してるのはこんなもんです!頑張りましょう!

    2014年12月23日火曜日

    CODE THANKS FESTIVALに参加してきたよ


    リクルートの主催する、CODE THANKS FESTIVAL 2014に参加してきました。場所は東京のテレコムセンタービルです。
    僕にとっては初めての競技プログラミングで、とても難しかった……

    CODE FESTIVALと並行した大会で、予選のあと、本戦に残れなかった人のうちの上位の人だけが参加可能でした。
    問題は
    http://code-thanks-festival-2014-b-open.contest.atcoder.jp/
    から見ることができます。僕の解答で良ければ、コードもお渡しします(コンテスト中のものなので、かなり汚いです)

    今回のコンテストは3hで8問も出されるので、全部解ける人なんていないと思っていたら・・・2人いました。すごいです・・・
    僕は結局8問中5問(A〜E)でした。五問以上解けた人は50人/85人程度でしたので、まあ微妙な感じです。ただ5問以上とけるとトートバッグがもらえました笑

    今回のコンテストはなによりも待遇が素晴らしく、交通費全額支給(¥28000程度)、昼食(叙々苑焼肉弁当)つき、(謎のTシャツ支給)、お菓子・ドリンク食べ放題で、懇親会では寿司などビュッフェ形式で出てきました。最高です。


    懇親会のときに同時開催されたものが、
      ・DDR(家庭用、マット使用)大会
      ・太鼓の達人(家庭用のたいこ使用)大会
      ・書道コーディング(書道で美しいコードを書くコンテスト)
    でした。

    上の写真が書道コーディングの作品たちです。

    それで、結論から言うと、書道コーディングでAtCoderの社長さん(高橋直大さん)から大賞を頂き、Amazonギフトカード¥3000までもらいました。僕の作品(?)は、
    です。画力0です。
    こちらは一人しか選ばれないので、非常に栄誉ある賞でとても嬉しいです笑

    また、このとき高橋直大さんに、プログラミングコンテストチャレンジブックの表紙の裏に、サインも頂きました笑
    世界で三番目にアルゴリズムプログラミングが出来る人・・・やばいです

    懇親会などでフォロワーが増え、なぜか京都の知り合いも増え、いい日でした。

    ついでに東京観光をして、等身大ガンダムをみたりした話はまたのちほど。

    2014年12月11日木曜日

    Swiftでの開発について


    2つ前の記事iOS Developer Programについて書きました。

    つまり手順を省略して書くと、Xcode(無料)さえあればSwift開発できるけど、実機デバッグするには有料の登録が必要、ということです



    Swiftはまだ新しい言語で、書ける人は少ない、とおもいきや、めっちゃ簡単に書ける言語でびっくりです!
    ドキュメントははじめこそ英語しかなかったですが、もう日本語もいっぱいでていて、初心者でも十分書き始められると思います!

    ただ、わざわざSwiftに手を出そうとしてる人はきっとCぐらい書けると思うので、そういう人向けのドキュメントを紹介します。
    (僕もまとめようかと思いましたが、既存のドキュメントで十分に揃っていますので、今後適宜、詰まった所や詰まりやすいところをご紹介していこうと思います)

    準備は上記の通り、Xcodeだけです!



    まずSwiftの入門として、僕がプログラミングを始めた中高時代にプログラミングを教えてくれていた先輩の記事
    CAMPHOR- Tech Blog
    すごく教えるのがうまい方で、とてもわかりやすいです。ただ、ToDoアプリを作ろう、のほうが少しまだエラーがあります。

    基礎がわかったら、応用として、
    Swift Docs
    がおすすめです。
    逆引きSwiftが強いです。正直、コピペだけで簡単なアプリが作れます



    オブジェクト志向については別で学ぶ必要があるかもしれませんが、この2つでかなりのことができるようになると思います。


    以下、少しだけ補足説明を。(CAMPHOR- Tech Blogを読み終わったあたりで読み返してみてください)



    ※Optional型について
    Swift独自の特徴としてOptional型の変数があります。
    var a: Int = 5
    var a: Int? = 5
    nil(空データ)をいれられるかどうかの違いですが、Swiftでは、変数を空にできないためにある仕様です。バグ防止のための仕様みたいですが、Cで言う"int a;"みたいなことができないことにはじめは戸惑うかもしれません

    ※CGFloatみたいな特殊な型について
    オブジェクト志向なので、変な名前の構造体やクラスがあるのは当然のことですが、CGFloatみたいな、特殊な変数の型もあります。Objective-Cをしていないと戸惑うと思います(僕もそうでした)
    これ実は裏ではtypedefされていて、たとえばCGFloatは64bitsシステムならdouble、32bitsシステムならfloatを表します。
    怯まずに進みましょう。