フツーって言うなぁ!

フツーなサラリーマンのフツーな嘆き.

内定式に行ってきました

修士論文の中間発表も終え,いよいよ修了が近づいてきた感があります.

10/1に,内定先の企業の内定式に参加してきました.
いわゆる「大手Web系企業」で,新卒者は総合職・技術職含めて200人ぐらいいた気がします.

式自体はわりとすぐに終わり,そこから研修・懇親会・2次会という流れでした.

研修はビッグデータ関連のお話で,私の興味にかぶっていたので面白かったです.

懇親会の2次会は,銀座のクラブ(?)を貸し切っての大きなものでした.
ああいった所での飲み会は経験がなかったので,自分には刺激が強かったです…*1

f:id:lethe2211:20141001212911j:plain


最近,「これから何して生きていこう」ということばかり考えているような気がします.
年を食うに連れ,生き方の選択肢は増えていきますが,その指針を教えてくれる人は少なく,なんとなく視野が狭くなっているように感じるのです.*2

とりあえず,あと半年何ができるかを考えていきたいです.

*1:ビジネス系の人はウェーイ系の学生が多かったです.エンジニアは最終的に僕らだけになり,いたたまれなくなって皆で抜けてきました…

*2:内定ブルーという奴です

Qiitaに初投稿しました

前々からやりたかったぼっちバーに行ったり,コンサートホールで音楽鑑賞したり,地味ながら充実した日々を送っている気がします.

タイトルの通り,エンジニア向けの支援サービスであるQiitaに初めて投稿しました.

一応,Qiitaがサービスを始めてから追ってはいましたが,正直,できた当初はここまで流行るとは思っていませんでした.

このサービスの魅力は,ひとえに「ポストのしやすさ」だと思います.
Markdown記法を採用し,マークアップも非常にシンプルです.
これだけだと普通のサービスっぽいですが,Qiitaが開発しているMacアプリのKobito がすごい.

KobitoはMarkdown形式に対応したエディタです.
Markdownをリアルタイムでマークアップしてくれるだけでもありがたいのに,そのままQiitaに投稿することもできる!*1
技術関係以外でも,ちょっとしたメモに使っています.

今回投稿した記事がこちら.

MacからUbuntuにSSH接続し,tmux上でマウスによるコピーアンドペーストを行う

Qiitaに投稿するようになると,技術ブログとしてのこちらの価値が危ういのですが…
どうやって住み分けしていきましょうか?

*1:なんか回し者みたい

Pythonで,文字列を構成する各文字を入れ替える

こういう細々としたネタも,書いてる人が他に見つからなさそうなら書いていくようにしたいです.

やりたかったこと

文字列sが与えられた時,sを構成する文字を入れ替えたい(例えば,'abc'の2番目の文字と3番目の文字を入れ替えて,'acb'にしたい).

Rubyなどとは違い,Pythonは文字列の変更(各要素に対する再代入)が許されていないため,そのままでは入れ替えができない.

[1] pry(main)> s = 'abc'
=> "abc"
[2] pry(main)> s[1], s[2] = s[2], s[1]
=> ["c", "b"]
[3] pry(main)> s
=> "acb" # ちゃんと入れ替わる
In [1]: s = 'abc'

In [2]: s[1], s[2] = s[2], s[1] # 要素に対しての再代入不可
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-5da7d18dd305> in <module>()
----> 1 s[1], s[2] = s[2], s[1]

TypeError: 'str' object does not support item assignment

環境はPython 2.7.5.

解決策

文字列のままでは変更できないのであれば,リストに変換すればいい.

In [11]: s = 'abc'

In [13]: list_s = list(s)

In [14]: list_s[1], list_s[2] = list_s[2], list_s[1]

In [15]: s = ''.join(list_s)

In [16]: s
Out[16]: 'acb' # ちゃんと入れ替わる

別の方法として,文字列全体に再代入して,

In [17]: s = 'abc'

In [18]: s =  '{0}{1}{2}{3}'.format(s[0:1], s[2], s[1], s[2:2])

In [19]: s
Out[19]: 'acb' # ちゃんと入れ替わる

みたいにしてもよい(少しめんどくさい気もする).

参考

文字列(3) - バリケンのPython日記 - pythonグループ

Pythonでリストの要素を一括で変換(文字列などに) | rakkyooの備忘録

POH Liteをやってみた

頭が悪すぎて研究室のプロコンで出遅れています.

8/27まで行われていたPaiza Online Hackathon Lite (POH Lite)に参加しました. 今度のネタは,プレイヤーが炎上案件を回避するプロの美少女ということで,少し趣向を変えてきた感じですねー.*1

今回は,前回に比べるとわりと良心的な問題設計になっていて,そこまで凝った解法でなくても100点を取れるようになっていた気がします.

gista541bb1ed3e39d22a8a3

DPを使うところまではわりとすぐにわかったのですが,今回追加する数値を2回数えてしまうという問題を解決するのに時間を取られました. DPテーブルの後ろ側から見ていくと,フラグなどを使わなくてもなんとかなるようです.

f:id:lethe2211:20140901135559p:plain


まだ高速化の余地はあるような気がしますが,とりあえずこんな感じで.

*1:こういうシチュエーションって大事ですよね

今やってる/やりたいこと

投稿論文の〆切が8月末で,久しぶりに夏休みの宿題に追われるカ○オくんのような気持ちになっております.
レテです.

書くネタがないまま前投稿から14日過ぎてしまったので,常にやりたいことを明文化して持っておくことは大事だと思うので,今やってる or やりたいけどできてないことでもメモしておこうと思います.

重要度:高

  • Unityによるゲーム制作

卒業制作として,友達とUnityを使ったゲームの制作を考えています.
いくつかステージのモックアップを作る程度には進んでいますが,まだまだといった印象です.

僕自身,なかなか時間が取れずに申し訳ないのですが,何とか冬辺りにリリースできたらいいなと思ってます.

いつの間にか試験まで2ヶ月切っているので,この前みたいにならないようにしたいです.

今は,少しづつ知識を入れている段階で,1冊教本を読み終わったら問題演習に移っていきたいです.

重要度:中

  • 英語の勉強

先月まで,TOEICを3ヶ月連続で受けました.

海外出張が決まったのも重なり,個人的にはそこそこ勉強のモチベーションを保てたのかなぁとは思います.

見知らぬ人に話しかけられても,何回か聞き直せば返事できるぐらいにはなったので,後は聞き直しの回数を減らすのと,適切な応答ができるようになりたいですね.

とりあえずスコア900を目指したいと思っています.*1

  • コーディング力の強化

プログラミングを勉強し始めた当初から,やりたいことは色々思いつくけど,それを実装するのが面倒ということで断念したことが多かったような気がします.

非常にもったいないことです.

コーディングに対する心理的障壁を減らしていきたいです.

プログラミングコンテストにちょくちょく参加しているのも,本気でアルゴリズムを極めるというよりは,そうした側面が強いかなと自分の中では考えています.

重要度:低

  • 京都の観光

京都にいられるのも後半年であると今更ながら気づいたので,観光名所やお祭りにはなるべく参加するようにしています.*2

毎年帰省の時期にあった五山の送り火や,納涼床などは今年経験しました.

おそらく,京都に(観光で)戻ってくることは何度かあると思いますが,北京都(鞍馬,大原など)にはなかなか行く機会がないと思うので,近くに住んでいる内にちょくちょく行っておきたいです.

後はラーメン巡りとかですかね.

*1:この辺まで来ると,TOEICの対策をしても点数はほとんど上がらなくて,本物の英語力,コミュニケーション力が問われるのだと思います

*2:京都は正直住み良い所ではなかったと思いますが,こういうイベントには事欠かなかったです

KUINS-IIIでSSHポートフォワーディングを用いて内部サーバにアクセスする

ネットワークも勉強しよう勉強しようと思いながら,全く進まなくていつもGoogle先生にお世話になっています.

研究室内でサーバを立てて実験に利用しているのですが,お盆で帰省したいのに研究室外からアクセスできないのはつらい!ということで,いろいろ調べてみたところ,解決策がありました.

京都大学が運営している学術情報ネットワークサービス(KUINS)では,SSHポートフォワーディングのサービスを行っており,これを使えばできるそうです…

やりたかったこと

学外のネットワークから学内のネットワークにあるサーバにSSHでリモートログインしたい.
OSはMac OS X Marvericks.

やり方

次のような状態を想定する.

client: 学外にあるマシン(Mac).これを使ってリモートログインしたい
target: 今回リモートログインして動かしたいサーバ(Linux).学内(この場合は研究室内)にあるので,もちろんそのままアクセスすることはできない
forward.ipse.media.kyoto-u.ac.jp: SSHサーバ.学外からのアクセスが可能になっており,SSHポートフォワーディングにおける中継役となっている

0. 研究室内からtargetにSSH接続できるようにしておく.
今回の話には関係ないので割愛.

1. 私の研究室(他の研究室も?)では学外からのアクセスの場合,1023番以下のポートへのアクセスは拒否される.
よって,サーバの1024番以上のポート番号をSSH接続用に開けておく必要がある.
今回は22222番ポートをSSH用に開ける.

私の環境では,SSH用の設定は,/etc/ssh/sshd_configに書かれていたので,これを修正する.

lethe@target$ sudo emacs /etc/ssh/sshd_config

lethe@target$ sudo /etc/init.d/ssh restart

2. clientによってSSHポートフォワーディングを行う.
今回は,localhostの30000番ポートをtargetの22222番ポートに対応させることとする.

lethe@client$ ssh -fN -L 30000:[targetのIPアドレス]:22222 [自分のECS-ID or SPS-ID]@forward.ipse.media.kyoto-u.ac.jp

接続には,京都大学の学生が持つECS-IDか,教職員が持つSPS-IDが必要.
接続の際にパスワードを求められるので,IDに対するパスワードを入力する.

3. clientによるSSH接続を行う.

lethe@client$ ssh -p 30000 lethe@localhost

問題がなければ,これでつながるはず.


ポートフォワーディングについては,資料を読んでも???という感じだったので,どこかでしっかり勉強したいです.

今までは,研究室に行かないと開発が進められない情弱進行だったのですが,少しはマシになりそうですね…*1

参考

K. Sato's Web Page

管理者必見! ネットワーク・コマンド集 - sshコマンド:ITpro

*1:どこでやろうが進まないものは進まない

PythonでcPickleを使用する際に,"maximum recursion depth exceeded"というエラーが出る

久しぶりにPythonの話をする気がします.
BeautifulSoupと(c)Pickleについてです.

問題

BeautifulSoupによってHTMLから取得した文字列を,cPickle*1を用いて保存しようとしました.

import filecache # ファイルキャッシュ用のプログラム(cPickleのラッパ.他人が書いたものなので見せられない)
from bs4 import BeautifulSoup # BeautifulSoupのバージョンは4
# (略)

class CiteSeerXCrawler(object):

    # (略)

    def get_abstract(self, url):
        '''
        入力としてURLを受け取り,CiteSeerXの論文詳細ページから,アブストラクトを返す
        '''
        abstract = ''

        html = self._get_html(url) # HTMLの取得

        soup = BeautifulSoup(html, 'html.parser') # BeautifulSoup

        if soup.find('div', {'id': 'abstract'}):
            soup_abstract = soup.find('div', {'id': 'abstract'}).p
            abstract = soup_abstract.string # BeautifulSoupにより取得した文字列 (*)
            # (**)
            return abstract

class GoogleScholarArticleCrawler(object):

    # (略)

    def get_abstract(self, cluster_id):
        '''
        Cluster_idを受け取り,対応する論文のアブストラクトを返す
        '''
        abspath = os.path.dirname(os.path.abspath(__file__))
        abstract = filecache.Client(abspath + '/abstract/')

        cache = abstract.get(str(cluster_id)) # キャッシュから取り出す
        if cache is not None and cache['status'] == 'OK':
            return cache['data']
        else:
            art = self.get_bibliography(cluster_id)

            result = {'status': '', 'data': []}

            # CiteSeerXによる引用論文の取得
            if art["title"][0] is not None:
                abst = ''
                c = CiteSeerXCrawler()
                search_results = c.search_with_title(art['title'][0], num=1)
                time.sleep(1)
                if len(search_results) > 0:
                    abst = c.get_abstract(search_results[0])
                    result['data'].append(abst) # 取得した文字列を追加

                if len(result['data']) > 0:
                    result['status'] = 'OK'
                    abstract.set(str(cluster_id), result) # キャッシュに保存
                else:
                    result['status'] = 'NG'

            return result['data']

すると,以下のようなエラーを吐いて,中身の無いファイルを出力してしまいます.

Traceback (most recent call last):  
  File "lib/crawler/google_scholar_abstract.py", line 15, in <module>  
    abstract = g.get_abstract(sys.argv[1])  
  File "/home/lethe/LiteratureSearchEngine/lib/crawler/google_scholar_article_crawler.py", line 233, in get_abstract  
    abstract.set(str(cluster_id), result)  
  File "/home/lethe/LiteratureSearchEngine/lib/crawler/filecache.py", line 46, in set
    pickle.dump(value)  
  File "/usr/lib/python2.7/copy_reg.py", line 74, in _reduce_ex  
    getstate = self.__getstate__  
RuntimeError: maximum recursion depth exceeded

解決策

BeautifulSoupの結果のstringを文字列と思い込んだのがまずかったらしい.

上のソースコードの(**)の部分に

print type(soup_abstract.string)

を挿入して,この変数の型を調べてみると,strではなく,

<class 'bs4.element.NavigableString'>

という,BeautifulSoup固有と思われる型が返ってきました.
つまり,strでもunicodeでもないということ.

python - pickle.dump meet RuntimeError: maximum recursion depth exceeded in cmp - Stack Overflow

ここらへんを見てる限り,BeautifulSoupのオブジェクトをそのままpickleに詰め込むのはまずいみたい.

(*)の部分を

abstract = unicode(soup_abstract.string)

にするとうまく動くらしいです.


最初,原因がBeautifulSoupにあるとわからず,必死にファイルキャッシュのコードを見直していて,半日潰しました…

悔しいので載せておきます.

*1:ざっと調べた限り,pickleについても同様の問題があるかと思われます