Beyond The Limit

はじまりは2001年

Python学習メモ4

タプル

タプルはリストと異なりイミュータブルである。 タプルを定義するのは括弧ではなく、カンマ。ただ括弧があれば分かりやすい。 要素が一つでも最後にカンマを入れる必要がある、入れなければただの変数格納になる。

>>> tapuru1 = 'AA', タプル
>>> tapuru1
('AA',)
>>> tapuru2 = ('BB',)  タプル
>>> tapuru2
('BB',)
>>> tapuru3 = 'CC' タプルではない
>>> tapuru3
'CC'
>>> tapuru4 = ('DD')   タプルではない
>>> tapuru4
'DD'
>>>

以下はタプルのアンパックと呼ばれる、タプルを使えば複数の変数を一度に代入できる

>>> tapuru5 = ('EE','FF','GG',)
>>> tapuru5
('EE', 'FF', 'GG')
>>> a,b,c = tapuru5    a,b,cにそれぞれ0,1,2の変数を格納する
>>> a
'EE'
>>> b
'FF'
>>> c
'GG'
>>>

入れ換えも簡単にできる

>>> aaa = '123' ここは変数代入
>>> bbb = '456'    ここも変数代入
>>> aaa,bbb = bbb,aaa  aaaとbbbを交換している
>>> aaa
'456'
>>> bbb
'123'
>>>

tuple(リスト名)を使えばリストからタプルへ変換もできる

辞書

他言語では連想配列やハッシュと呼ばれるもの

In [10]: testdic = { {で始まり
"day1" : "a day",   :で区切り、最後がカンマ
"day2" : "perfect day",
}   }で締める

dict()関数を使えば、2要素のシーケンスを辞書に変換できる

>>> list1 = ['a1','b2','c3','d4']
>>> dict(list1)
{'a': '1', 'c': '3', 'd': '4', 'b': '2'}    変換された、辞書内の順番は決まっていないのでばらばらになる
>>>

辞書のキーを表示させる

>>> dict1 = dict(list1)
>>> dict1
{'a': '1', 'c': '3', 'd': '4', 'b': '2'}
>>>
>>> dict1['a']
'1'
>>> dict1['a'] = 10    キーaの値を変更
>>> dict1['a']
10
>>> dict1
{'a': 10, 'c': '3', 'd': '4', 'b': '2'} aが10に変わっている
>>>

update()で辞書の"結合"ができる

>>> list2 = ['e5','f6'] list2に新しい値を入れておく
>>> dict2 = dict(list2)    dict2にlist2を辞書変換したものを入れる
>>> dict2  辞書変換されている
{'f': '6', 'e': '5'}
>>> dict1  dict1の中身を表示
{'a': 10, 'c': '3', 'd': '4', 'b': '2'}
>>> dict1.update(dict2)    dict1にdict2を追加
>>> dict1  dict2のe5とf6が追加されている、dict2の中身は消えずにそのまま。仮にdict1とdict2のキーが被っていた場合は後からきたもの(dict2)の値で上書きされる
{'a': 10, 'd': '4', 'e': '5', 'f': '6', 'c': '3', 'b': '2'}
>>>

del文でキーを指定するとキーと要素を削除出来る

>>> dict2
{'f': '6', 'e': '5'}
>>> del dict2['f'] ''がないとエラーが出る
>>> dict2  f6の要素が消えている
{'e': '5'}
>>>

[key]を指定すると辞書にキーが追加出来る

>>> dict2
{'e': '5'}
>>> dict2['f'] = 6
>>> dict2  f6が増えた
{'f': 6, 'e': '5'}
>>>

clear()で辞書の中身を全て消去できる

>>> dict2
{'f': 6, 'e': '5'}
>>> dict2.clear()
>>> dict2  消えた
{}
>>>

inで要素の有無を確認できる

>>> dict1
{'a': 10, 'd': '4', 'e': '5', 'f': '6', 'c': '3', 'b': '2'}
>>> 'a' in dict1   キーを指定する
True
>>> '10' in dict1  値は指定しない
False
>>>

辞書から要素を取り出すときに辞書専用のget()関数を使うと色々できる

>>> dict1.get('a')  普通に要素を取り出す
10
>>> dict1.get('10','Not Found')    指定したキーが無い場合は'Not Found'を返す
'Not Found'
>>> dict1.get('10')    オプション(Not Foundのとこ)が無ければNoneになる
>>>

kyes()で全てのキーを返す、values()で全ての値を返す

>>> dict1
{'a': 10, 'd': '4', 'e': '5', 'f': '6', 'c': '3', 'b': '2'}
>>> dict1.keys()
dict_keys(['a', 'd', 'e', 'f', 'c', 'b'])
>>> dict1.values()
dict_values([10, '4', '5', '6', '3', '2'])
>>>

keys()やvalues()で返ってきたものをリスト化する

>>> list(dict1.keys())  list関数の中で呼び出す
['a', 'd', 'e', 'f', 'c', 'b']
>>> list(dict1.keys())[0]  list[0]を取り出した状態
'a'
>>>

items()でkeyとvalueのセットが全て返ってくる

>>> dict1.items()   全て返ってきた
dict_items([('a', 10), ('d', '4'), ('e', '5'), ('f', '6'), ('c', '3'), ('b', '2')])
>>> list(dict1.items())    全て返してlist化した、タプルで返ってくる
[('a', 10), ('d', '4'), ('e', '5'), ('f', '6'), ('c', '3'), ('b', '2')]
>>> list(dict1.items())[0] list化して最初のセットを取り出した状態、タプルで返ってくる
('a', 10)
>>>

辞書の場合も元の辞書が=で書き換えられてしまったら、コピーしたものも書き換わる。 必要に応じてcopy()で元の辞書を書き換えても影響が内容にする。

集合

集合は値を取り出してキーだけを残した辞書のようなもの。

set()で作るか{}で値のみを入れて作る

>>> syuugou1 = set()    空の場合、実際には空の辞書が作られる
>>> syuugou1
set()
>>> syuugou1 = {   値のある集合
... 1,2,3,4,5
... }
>>> syuugou1
{1, 2, 3, 4, 5}
>>>

文字列から集合を作る場合

>>> set('letters')
{'s', 'e', 'r', 'l', 't'}   重複している文字は省かれる
>>>
>>> set({'1':'a','2':'b','3':'c',})    辞書を渡す
{'1', '3', '2'} キーのみ使われる
>>>

&またはintersection()を使うと積集合(両方にある共通の要素)が出力される

>>> a = {1,2}
>>> b = {2,3}
>>> a & b
{2}
>>> a.intersection(b)
{2}
>>>

|またはunion()を使うと和集合(どちらか片方にある要素)が出力される

>>> a | b
{1, 2, 3}
>>> a.union(b)
{1, 2, 3}
>>>

-またはdifference()を使うと差集合(先のものにあって後ろのものにないもの)が出力される

>>> a - b   aには1はあるが、bには1がない
{1}
>>> b -a   bには3はあるが、aには3がない
{3}
>>> a.difference(b)
{1}
>>> b.difference(a)
{3}
>>>

^またはsymmetric_difference()を使うと排他的OR(どちらか片方には含まれているが、両方には含まれていない要素)が出力される

>>> a ^ b
{1, 3}  両方に2が有るので、それ以外が表示される
>>> a.symmetric_difference(b)
{1, 3}
>>> c = {4,5}
>>> a.symmetric_difference(c)
{1, 2, 4, 5}    両方ともで被っているものはないので、全て表示される
>>>

<=またはissubset()を使うと部分集合になっているかどうかをチェックできる

>>> a <= b
False
>>>
>>> d = {1,2}
>>> a <= d  dはaの要素を全て含んでいるのでTrueが返る
True
>>> d = {1,2,3}
>>> d
{1, 2, 3}
>>> a <= d      dはaの要素を全て含んでいるのでTrueが返る
True
>>>

補足

<を使うと真部分集合になっているかどうかをチェックできる

>=を使うと上位集合になっていえるかどうかをチェックできる

>を使うと真上位集合になっているかどうかをチェックする。

セールスエンジニアという役割で半年仕事をしてみて

こんにちは、はてなのMackerelチームでセールスエンジニアをしているid:sharataniです。 本日ははてなデベロッパアドベントカレンダーの一環として記事を書きました、昨日はid:astjさんです。

developer.hatenastaff.com

実ははてなではセールスエンジニアという職種は私しかおらず、この職種での採用も初めてだったそうです。

セールスエンジニアといっても業界によって趣が異なるところもあり、会社によっても呼称が様々だったりするようです。 最近参加している勉強会でもその話題が出てくることもあり、会社によってはエバンジェリスト・セキュリティアーキテクト・システムアーキテクト等の呼称で採用をしているところもあるようです。

私自身もあまり馴染みが無かったこともあり、どんな仕事をしているのか(私の場合となりますが)ご紹介させていただきます。

セールスエンジニアとは

"セールスエンジニアとは"で検索してみたところ、いくつか記事が見つかりました。

セールスエンジニアとは、どんな仕事?|エンジャパンの転職大辞典|エン転職

プリセールス・セールスエンジニアの仕事内容とは。働き方から平均年収、未経験からの就職のコツまで解説! | 職種図鑑 |転職@type

セールスエンジニアの仕事内容 | Find Job !

セールスエンジニア | 大学・学部・資格情報 | Benesse マナビジョン

セールス+エンジニア=セールスエンジニア、なのでセールスのことも理解しつつ、エンジニア的なことも理解をしなければいけません。 エンジニアがそうであるように、セールスと一言で表現しても幅が広く、奥も深いものです。

セールス・エンジニア両方の視点を持った上で仕事をしないといけないのですが、仕事の幅が広い分やること・やらないといけないこと・やった方がいいことは多岐に渡ります。 むしろ"やらなくていいこと"というのはあまり無いと感じています。

具体的にどんなことをしているのか

私が入社したのは半年前になりますが、この半年でこんな仕事をしてきました。

  • セールス
    • お客様訪問
    • お客様先でのハンズオンや説明会の実施
  • マーケティング
    • 競合サービス・ツールの調査や使用感の確認、連携事業者様との協業展開
  • イベント
    • Mackerelミートアップやドリンクアップの実施
    • 実施会場の選定・提供企業様との調整・登壇者様への依頼、その他細かいこと
    • イベント結果のまとめ
  • Mackerelのフィードバック・サポート
    • 弊社のサポート部やMackerelの開発メンバーと協力して対応しています
  • Mackerelヘルプの更新
    • フィードバックや質問の内容から問い合わせ傾向を把握し、ヘルプの更新をします
  • Mackerelの検証作業
    • 新しい機能が出た時やサポート宛に問い合わせをいただく中で検証作業を行います

タイミングによっては1週間のうち毎日どこかに出かけてMackerelの話をすることもありますし、日に2〜3件ほどお客様訪問をする時もあります。 もちろん一つのことに集中して仕事をすることもありますが、足を動かしつつ、手を動かしつつ、頭で考えつつ、色々なものが同時に進行していきます。

どんな仕事でも求められることだとは思いますが、複数のことを並行して処理を進めることやバランス感覚がとても大事です。 そしてセールス・マーケティングを行う上での技術に関する下地も大切なので、日々の勉強を継続することも欠かせません。

こうやって書いてみるといわゆる"何でも屋"的な側面もあるように思いますが、技術に興味がある・技術が好き・ITが好き・色々なことをやってみたいという人にとっては向いている仕事なのかもしれません。 Mackerelの提案・サポート・ヘルプの更新はエンジニア職や技術職の経験が無いと難しいですし、何よりも技術に対する興味がなければ務まりません。 セールスエンジニアという職種の"エンジニア"部分はある程度の技術的な基盤・下地がないと難しい仕事だなと感じた半年でもありました。

セールスエンジニアに必要なもの

セールスエンジニアとはどんな仕事なのか、私の場合は具体的にどんな仕事をしているのかを簡単に書いてみました。 最後にセールスエンジニアに必要なものとして、技術力・提案力・推進力もそうですが、一番は"プロダクトに対する愛"ではないかなと思います。

プロダクトに対する愛というのは人それぞれだと思いますが、かつて運用周りの仕事をしていた際、モニタリング周りで苦労をしていました。 当時苦労したという自分の経験からも「Mackerelはこんなに簡単にインストールが出来て、キレイなグラフが表示されて設定も簡単で日本語のヘルプもあってとても便利に使える、知らない人には知って欲しいし、苦労をしている人には楽になって欲しい。」と思っています。 この過去の経験とMackerelの良さがプロダクトへの愛にもつながっていますし、この仕事をやってみたいという入社への動機にもつながりました。

最後に

いわゆるフィードバック・サポートへの問い合わせというと、要望や質問を書いて送信することが多いと思います。 しかし、この半年を通じてサービスを利用することで従来と比較して楽になった・助かった・良かったということも一つのありがたいフィードバックであり、サービスを提供している人への応援メッセージだということがよく分かりました。

改めて自分自身が利用している他の素晴らしいWEBサービスにも、そのようにサービスの良い点・助かった点などをフィードバックとして送信しようと思うようになりました。

明日は同じMackerelチームのアプリケーションエンジニアでもある、id:stefafafanが担当です。(社内では隣の席です)

Python学習メモ3

文字列の続き、リスト

append()

末尾に要素を追加する。

extend()

リストの結合をする。

+= リスト名でも同じことができる。

insert()

位置を指定して様子を追加する。

insert(2, 'aaa')といった使い方をする、2がオフセット。

del

オフセットを指定して要素を削除する。

del aaa[1]といった使い方をする、delは文なのでaaa[1].del()とは書かない。

remove

値を指定して要素を削除する。

aaa.remove('A')といった使い方をする、Aが消える。オフセット位置が分からない場合などに利用。

pop

要素を取り出して削除する、取り出すので代入も可能。

In [20]: aaa = ['A','B','C']
In [21]: bbb = aaa.pop(0)
In [22]: bbb
Out[22]: 'A'

index

値を指定してオフセットを確認。

aaa.index.('A')といった使い方をする、Aのオフセットを返す。

in

値がリストの中に存在するかどうかを返す、同じものが複数存在している場合は1箇所でも同じものがあればTrueを返す。

In [38]: 'A' in aaa
Out[38]: True

count

特定の値がリスト内に何個含まれているかを返す。

aaa.count('探したい文言')などで検索する

sort/sorted

並べ替えをする、sortは元のデータを書き換える、sortedは元のデータを書き換えない

sortedの例

In [61]: aaa
Out[61]: ['ABC', 'XYZ', 'TW']

In [62]: sorted(aaa)
Out[62]: ['ABC', 'TW', 'XYZ']

In [63]: aaa
Out[63]: ['ABC', 'XYZ', 'TW']   並べ変わっていない

sortの例

In [63]: aaa
Out[63]: ['ABC', 'XYZ', 'TW']

In [64]: aaa.sort()

In [65]: aaa
Out[65]: ['ABC', 'TW', 'XYZ']   元のデータが並べ変わっている

In [67]: aaa.sort(reverse=True) reverse=Trueを付けると逆順になる

In [68]: aaa
Out[68]: ['XYZ', 'TW', 'ABC']

len

要素の数を返す

len(aaa)というように使う

=とcopy

リストの場合"="は代入なので、元が変わるとそれにつられて他のものも変わる

ただし通常の変数代入の場合はつられて変わらない

In [1]: aaa = ['A','B','C']

In [2]: aaa
Out[2]: ['A', 'B', 'C']

In [3]: bbb = aaa

In [4]: bbb
Out[4]: ['A', 'B', 'C']

In [5]: aaa[0] = '1'    リストaaaの0番目を1に変更

In [6]: aaa
Out[6]: ['1', 'B', 'C'] 0番目が1になっている

In [7]: bbb
Out[7]: ['1', 'B', 'C'] 元のデータが変わっているのでbbbも変わっている

In [8]: bbb[1] = 'Z'    bbbの1番目をZに変える

In [9]: bbb
Out[9]: ['1', 'Z', 'C']

In [10]: aaa
Out[10]: ['1', 'Z', 'C']    元のaaaの1番目もZに変わっている

copy関数、list()変換関数、リストスライスでコピーすると元の値が変わっても影響を受けない

In [11]: a = ['1','2','3']

In [12]: a
Out[12]: ['1', '2', '3']

In [13]: b = a.copy()   copy関数

In [14]: b
Out[14]: ['1', '2', '3']

In [15]: c = list(a)    list()変換関数

In [16]: d = a[:]   リストスライス

In [17]: a[0] = '8' 元データの0番目の値を変更

In [18]: a
Out[18]: ['8', '2', '3']    変わってる

In [19]: b
Out[19]: ['1', '2', '3']    影響なし

In [20]: c
Out[20]: ['1', '2', '3']    影響なし

In [21]: d
Out[21]: ['1', '2', '3']    影響なし

Python学習メモ2

文字列

Pythonのスライスは[start:end:step]

aaa = "ABCDE"
>>> aaa
'ABCDE'
>>> aaa[:] 特に何も指定しなければ全て返す
'ABCDE'
>>> aaa[1:]    start、startは指定された位置から始まる
'BCDE'
>>> aaa[:3]    end、endの場合はend-1の位置までを返すので注意
'ABC'
>>> aaa[2:4]   start:end、この場合もendはend-1の位置までを返すので注意
'CD'
>>> aaa = "ABCDEFGHIJ"
>>> aaa
'ABCDEFGHIJ'
>>> aaa[0:100:2]   start:end:step、この場合はstep文字ごとにstartからend-1までの位置までを返す
'ACEGI'
0,2,4,6,8の位置

その他例

>>> aaa = "0123456789"
>>> aaa[3:-3]  start:4文字目、end:後ろから3文字目の手前(-1を返す)
'3456'
>>> aaa[::2]   start,endを指定せずにstepのみも指定できる、start::stepや:end:stepも出来る
'02468'
>>> aaa[::-1]  stepに負の数を入れると逆ステップになる
'9876543210'
>>>

リスト

文字列はイミュータブルなので文字列の文字を書き換えることは出来ないが、リストはミュータブルなので変更ができる list()で他のデータ型をリスト型に変換出来る

>>> aaa
'ABCDEFGHIJK'
>>> list(aaa)
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']
>>> list(aaa)[0]
'A'
>>>

タプルの場合

>>> tuple = ('GO1','GO2','GO3')
>>> print(tuple)
('GO1', 'GO2', 'GO3')
>>> tuple
('GO1', 'GO2', 'GO3')
>>> list(tuple)
['GO1', 'GO2', 'GO3']
>>>

リストをリストにすることもできる、2重構造にも3重構造にもできる

>>> aaa = ['AB','CD','EF']
>>> list(aaa)
['AB', 'CD', 'EF']
>>> aaa
['AB', 'CD', 'EF']
>>> bbb = ['HI','JK']
>>>
>>> ccc = [aaa,bbb]
>>> ccc
[['AB', 'CD', 'EF'], ['HI', 'JK']]
>>>
>>> ccc[0] cccリストの最初のリスト
['AB', 'CD', 'EF']
>>>
>>> ccc[0][0]  cccリストの最初のリストの最初のブロック
'AB'
>>> ccc[1][1]  cccリストの2つめのリストの2つめのブロック
'JK'
>>>

リストはミュータブルなのでリストの要素を書き換えることもできる

>>> xyz = ['123','456','789']
>>> xyz[1] = 'ABC'
>>> xyz
['123', 'ABC', '789']
>>>

タプルの場合はできない

>>> tuple
('GO1', 'GO2', 'GO3')
>>> tuple[0]
'GO1'
>>> tuple[0] = 'XY'    エラーが出て書き換えられない
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>>

Python学習メモ1

オライリーの入門Python3より。

型確認

type(変数名) で変数の型が返ってくる

>>> a = 7
>>> type(a)
<class 'int'>

>>> a = "あいうえお"
>>> type(a)
<class 'str'>

>>> type(1.0)
<class 'float'>

こんな感じ

数値

除算 /の場合は浮動小数点で結果を返す、//の場合は結果は切り捨てになる

>>> 3/4
0.75
>>> 3//4
0

型の変換 int(値)で整数型、float(値)で浮動小数点型へ変換される

>>> int(9.1)
9

>>> int(abc)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'abc' is not defined

True=1,Flase=0,true=エラー,false=エラーになる。

True/Falseはブール型なので0か1に変換される。

>>> int(true)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'true' is not defined

>>> int(True)
1

intの場合は文字列・数値を文字列扱いすると変換しない。

floatの場合は数値を文字列扱いしても変換する。

>>> int(1.0e3)
1000
---
>>> int ('1.0')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '1.0'
>>>
---
>>> float ('1.0')
1.0
---
>>> int(1.0)
1

文字列

Pythonの文字列はイミュータブルである。

シングルクォートもダブルクォートも3つ使うことができる、文章が長い場合に始まりと終わりを表す。

>>>a = ''' abc def
... hig
... kas
... '''
>>> 

>>> print (a)
 abc def
hig
kas

>>>

こんな感じに複数行対応している、シングル/ダブルクォートもダブルクォートが1つの場合は改行時にエラーが出る。

>>> a = 'abc
  File "<stdin>", line 1
    a = 'abc
           ^
SyntaxError: EOL while scanning string literal
>>>

print()を使わない場合は改行は改行コードで表示される

>>> a
' abc def\nhig\nkas\n'
>>>

空文字列はシングル/ダブルクォートを入力することで作ることができる

他の文字列から新しく文字列を組み立てたい時に使う。

+=などの場合は予め空文字列で変数に何か代入しておく必要がある

>>> base = ""
>>> base += "あいうえお"
>>> base
'あいうえお'
>>>

>>> bake += "あいうえお"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'bake' is not defined
>>>

>>> bake = "あいうえお"
>>> bake
'あいうえお'
>>>

所感

pythonインタプリタで気になる動作があったので、調べていたらはやぶささんのブログにたどり着いた。 世界は狭い。

はてなに入って半年が経ちました〜半年目線〜

こんにちは、はてなでMackerelセールスエンジニアをしているid:sharataniです。
はてなスタッフアドベントカレンダーの一環で「はてな」に関することをテーマにしてブログ記事を書くこととなりました。
昨日はid:Swatzさんとid:mohritarohさんでした

advent.hatenablog.com

自己紹介

私は今年の6月に渋谷にある会社を退職し、同月にはてなに入社しました。
まさかはてなに入社するとは思っていなかったので、30超えても人生何が起きるか分からないものだなと感慨深かったのを覚えています。
応募〜入社までも色々とありました。

何やってるの?

MackerelというSaaSのサーバー・パフォーマンス監視サービスのセールスエンジニアとして働いています。
セールスエンジニアという職種は私だけなのですが、そちらの話ははてなデベロッパアドベントカレンダーの時に書こうと思います。
developer.hatenastaff.com

何書くの?

はてな」は2001年創業のため、インターネット系ベンチャー企業としては歴史もあり、インターネット上で色々な情報が見つかります。
しかし、あまり知られていない(単に自分自身が入社するまで知らなかったのかも)こともあり、この半年での気づきなどを簡単にまとめてみたいと思います。

1.入社時に好きなPCが選べる

エンジニア・デザイナー系とそれ以外の職種で分かれるようですが、一定の範囲内で好きなPCを選ぶことができます。
個人的な所感ですが、エンジニア・デザイナーはMacが多い、ビジネス系(営業・コーポレート)はWindowsが多いという印象です。

2.マウス・キーボードの購入に補助が出る

入社時に一定の範囲内で好きなPCを選べる会社は増えていますが、マウス・キーボードの購入に関して補助が出る会社はあまりないように思います。
手に馴染んだものを使いたいからちょっとお金を出しても自分が使いやすいものを購入する、そんな人は多いのではないでしょうか?
結構な金額の補助が出るので、自前で用意する人にとっては地味に有り難いです。
自前で買いましたが、私は会社では有線のApple キーボードとロジクールのMX Masterを使っています。

3.好きな椅子を選べる

インターネット系企業ではエンジニア向けによく見られる福利厚生の一つですが、はてなではアーロンチェアを用意しています。
しかし私の場合はアーロンチェアの後ろに沈み込む感覚がダメだったため、オカムラのシルフィに座って仕事をしています。
こちらも一定の金額内であれば会社から用意してもらえるため、快適に仕事ができます。
社内では椅子の代わりにバランスボールで仕事をしている人も結構多いです。

4.帰宅が早い

はてなは10時始業、19時終業なのですが、残って仕事をしている人の方が珍しくて目立つ、というぐらいに、みんな帰宅が早いです。(残業代が出ないというわけではない)
仕事をうまくこなしつつ、プライベートでの過ごし方も充実しているという人がとても多いように感じます。

5.社内ではIDで呼んでいる

なので本名を知らない・忘れる、などがたまにあったりします。
最初はびっくりしましたが、慣れるとそれが普通になってしまいます。慣れって怖い。
Mackerelのドリンクアップ・ミートアップといったイベントの懇親会でお客さんへエンジニアを紹介することもあるのですが、紹介するエンジニアの名字がうっかり出てこないこともあったりなかったりします。
IDなのであだ名とはちょっと違うかもしれませんが、名字で呼び合うよりも親近感がわくように思います。
渋谷のとある企業もあだなで呼び合う文化だと聞いたことがありますが、そういったことも社内の雰囲気の良さに一役買っているのかもしれません。

6.衣類が支給される(福利厚生の一環)

毎年一般販売される「はてなTシャツ」ですが、従業員にも福利厚生の一環として好きなデザイン・好きなサイズのものが支給されます。
私が所属しているMackerelチームではMackerelポロシャツ・Mackerelパーカーなどもあり、こちらも支給されます。(イベントとかで着てるやつです)

7.自席以外でも自由に仕事ができる

はてなには3FにSHIBAFUとよばれる多目的ルームがあるのですが、SHIBAFUにあるテントやリクライニングベッド(っぽいもの)で仕事をすることもできます。
来社いただいた方とTATAMI(掘りごたつのある会議室)やSHIBAFUで打ち合わせをすることもありますが、もちろん部屋が空いていればTATAMIで仕事をすることもできます。
基本的にノートPC+27インチの外部ディスプレイという環境なので、PCさえあれば社内のどこでも仕事ができるという感じです。

8.何だかんだで京都に行く機会が多い

チームや職種によっても変わってきますが、何だかんだで月に1〜2度は京都本社に行っています。
Mackerel自体が関西圏でも知名度・認知度が上がりつつあることもあったり、京都・愛知にも開発メンバーがいるので顔を合わせようという一環でもあります。
たまに「京都観光が出来て羨ましい」と言われることもありますが、仕事が終わるのは19時で東京に帰ろうと思うと21時半が終電なので、あんまりそういうものでもなかったりします。

9.あまりお金を使わなくなった

前職では渋谷勤務だったため、昼ご飯は桜丘や渋谷駅近辺が多かったです。
だいたい800円〜1000円の間で昼ご飯を食べることが多く、1ヶ月に換算すると1万6千円〜2万円の出費になります。
しかしはてなでは昼食に毎日まかないランチがでて、飲み物(お茶・コーヒー・ジュース)もお菓子類も自由なので、あまりお金を使わなくなりました。
たまに外出先で昼食を食べる際は昼ご飯にお金を出すということにハッとします。
まかないランチは強制ではなく自由なので、外に出て食べてもいいのですが、青山ではほぼ100%の人がまかないランチを食べてます

10.季節感を感じることが多い

仕事の忙しさなどで季節感を感じるということではなく、社内のイベントやちょっとしたことでも季節感を感じることが多いです。
今の時期ではクリスマスが近いこともあり、この前出社したら入り口の受付にクリスマスツリーが飾ってありました。
あまり知られていませんが、ハロウィンの時期には社内で仮装コンテストが開かれたりもします(テレビでも取材されました)
f:id:sharatani:20151214105448j:plain


などなど、会社によっては一部の福利厚生の対象がエンジニアだけが対象ということもありますが、はてなではあまりそういうこともなく、とても過ごしやすい・働きやすい良い会社です。


私のはてなとの出会い

個人的な話ですが、私が会社としての「はてな」を知ったのは、10年ほど前にITmediaに掲載されたこの記事でした。
www.itmedia.co.jp

当時は単純にid:naoyaさんというすごい人が、はてなという変わった名前の会社に入社して、なんかすごいことをやっているんだろうという認識でした。
当時は「自分には無縁だな」と思っていましたが、あれから10年経ち、社内・社外のスゴイ人たちと一緒に仕事をしています。
何をやるのか、何ができるのかは仕事をする上でとても大事なことですが、誰とやるかというのも同じぐらいとてもとても大事なことだと思います。


はてな」ではエンジニアと言わず、色々な職種で募集をしています。
もし興味がある方がいましたら、私含むはてなスタッフまで気軽にご連絡いただくか、採用ページからぜひ応募してみてください。
hatenacorp.jp


明日はid:astjさんとid:sallymyloveさんです

SQL学び直し13

第八章:SQLで高度な処理を行う

8-1:ウインドウ関数

  • ウインドウ関数とはOLAP(OnLine Analytical Processing)関数とも呼ばれる
    • OLAPとはリアルタイムにデータ分析を行う処理のこと
  • 構文:ウインドウ関数 OVER ( PARTITION BY <列リスト> ORDER BY <ソート用列リスト>)
    • rank over (partition by A orderby B) as ranking from table といった形で使う、A列毎にB列順にrankingカラムでランクを付けてくれる
  • ウインドウ関数は集約関数をウインドウ関数として使う、ウインドウ専用関数を使う、の2種類に分けられることができる
  • partition byによって区切られたレコードの集合をウインドウと呼ぶ、窓ではなく範囲を表わす
  • partition byを使わない場合、テーブル全体が1つのウインドウとしてみなされる(order byのカラム基準になる)
  • 以下、各ウインドウ専用関数の違い
    • rank()の場合に1位が3つある場合、1位、1位、1位、4位と飛ぶ
    • dense_rank()の場合に1位が3つある場合は1位、1位、1位、2位と飛ばない、デンスランクと読む
    • row_number()の場合に1位が3つある場合は1位、2位、3位、4位と同じ値でも2位と3位になる、同じ値の場合はDBMSが適当に値を振る
      • ウインドウ専用関数を使う時は()の中は空のまま使う、これは全てのウインドウ専用関数で同じ、引数を取らない
  • ウインドウ関数h原則としてSELECT句のみで使える、AVGやSUMを利用すると降順・昇順でのその時点での累計や累計の平均を出力出来る
  • 移動平均を出す場合
    • avg(カラムA) over(order by カラムB rows 直近の何行か数値を入れる preceding) as ~
    • その値の直近3行分の平均値をasの中に入れられる、precedingは前のという意味
    • カレントレコードから後ろを対象にするには、following(後の)を使う
    • 前後を対象にする場合は(order by A rows between 前の分の数値 preceding and 後ろの分の数値 following) as ~とする
  • OVER句の中のorder byはウインドウ関数がどういった順序で計算数かを決めるだけの役割しか持っていない、結果の並び替えには影響しない

8-2:GROUPING演算子

  • グループ化した結果の合計を求めることができる、ROLLUP、CUBE、GROUPING SETSの3種類がある
  • と思ったら、postgresqlではサポートされていないらしい

今日はここまで、長かったけど終わった。
とても勉強になったし、実務でも役立ったし、良い本でした。

SQL学び直し12

第七章:集合演算

7-2:結合(テーブルを列方向に連結する)

  • 結合の基本は内部結合と外部結合
  • 内部結合:select ... from A inner join B on A.x = B.y というような構文
  • 外部結合:片方のテーブルの情報がすべて出力される
    • from A left outer join B on A.x =B.y という場合はテーブルAのデータが全て出力される
    • from A right outer join B on A.x =B.y という場合はテーブルBのデータが全て出力される
  • クロス結合:select ... from A cross join B というような構文
    • すべての組み合わせ(直積)結果を出力する
  • 外部結合、クロス結合はあまり使わない
  • NULLを他の値に置き換える関数「COALESCE」を併用することが多い

今日はここまで。

SQL学び直し11

第六章:関数、術語、CASE式

6-3:CASE式

  • 単純CASE式と検索CASE式の2種類がある、検索CASE式は単純CASE式の機能を全て含む
  • 検索CASE式は以下のような式になる
CASE WHEN <評価式> THEN <式>
          WHEN <評価式> THEN <式>...
          ELSE <式>
END
  • 最後のENDは必須、ELSEは省略しても良いが可読性が落ちるので省略しない

第七章:集合演算

7-1:テーブルの足し算と引き算

  • UNION、テーブルの足し算
    • select AAA from B union select CCC from D; というような感じになる、重複行を排除して各テーブルが合体されたものが表示される
    • UNION ALLで重複行も表示される
  • INTERSECT、テーブルの共通部分のみ抽出
    • select AAA from B intersect select CCC from D; というような感じになる、共通しているレコードのみ出力される
  • EXCEPT、レコードの引き算
    • select AAA from B except select CCC from D; というような感じになる、テーブルBからテーブルDと重複したものを排除して出力される

今日はここまで。

SQL学び直し10

第六章:関数、術語、CASE式

6-2:術語

  • 術語とは戻り値が真理値(TRUE/FALSE/UNKNOWN)のいずれかになるもの
  • LIKE検索にて、%は0文字以上の任意の文字列、_は任意の一文字を現す(__だと任意の2文字)
  • BETWEENは範囲検索
  • IS NULLはnullを検索、IS NOT NULLはnullを外して検索
  • INはORを省略したもの、IN(A,B,C)というように使う、AまたはBまたはCとなる
  • NOT INはINの否定、NOT IN(A,B,C)というように使う、AでもなくBでもなくCでもないものとなる
  • INにはサブクエリを利用することができる
  • IN( SELECT...)と記述する、括弧内の結果が複数行であっても全てORで検索対象にしてくれる
  • サブクエリを使ってSQLを組んでおけば、メンテナンスフリーの度合いが強まる
  • EXISTS術語は「ある条件に合致するレコードの存在有無」を調べる、あればTRUE、なければFALSEを返す
  • EXISTSの引数は常に相関サブクエリを指定する、常にSELECT *を使う

今日はここまで。