筋トレを続ける話

筋トレ暦はだいたい10ヶ月程度で、好きなトレーニングはラッドプル・ダウンの25歳男性です。ガチ勢というわけではないのですが やっぱり「続ける」というのが何よりも大切だと思うのでそういう内容で書いていきます。

継続のポイント

継続のポイントはとにかく、他人を巻き込むことだと思っています。僕の場合はもともと友人に誘われて始めた筋トレですが、仲間内で誘い合いながらジムに行くようにしていると少し間が空いてしまったなあというときには友達が誘ってくれて習慣が途切れないようなきっかけになります。あるいは筋トレ歴が長い友人が、自分より圧倒的に高い負荷をかけながらワッセワッセとバーベルを上げている姿を見るとやる気にならざるをえません。ストイックに己の克己心のみで体を追い込み続けるのも良いのですが、意思の弱さを緩めのコミュニティによるちょびっとの強制力で補うのが僕のオススメです。 

僕がやっていること

みんなで筋トレをする、と言っても毎回予定がうまく合うわけでもないので ジムに行く時は誘うという感じのスタイルにしています。僕の場合は家にダンベルがあるのでダンベルでできるトレーニングは家でやり、ベンチやその他のマシンを使って盛大に己と戦いたい時に友人を誘いジムへと赴く感じです。だいたい家でのトレーニングとジムで、合わせて週2というのが自分にとっては理想のペースで、無理なく続けられる範囲かなという感じです。とにかく緩く無理なく、継続的にというのがテーマです。

だいたいジムに行く時は仕事終わりに行くのですがトレーニング後はみんなでご飯を食べたりする時間にもなるので、懐かしい部活の後のような時間を過ごせてそこもまたモチベーションの維持に繋がります。もともとが友達なので、筋トレ時に遊ぶ予定を決めたりすると大変スムーズにプライベートの充実が図れて一石二鳥です。

ツールに関しては、LINEでグループを作るのみで他には特に何も使っていません。毎週固定の曜日で参加者を募っていくという感じでもなく、本当に緩く誰からともなく誘うというだけで継続してるので、これは元々が友人であるからこその強みなのかなと思います。気を使うような間柄であると「最初に誘う人」の心理的ハードルはめっちゃ高いはずなので、こういうつながり方をするのであれば気を置けない間柄の人に限られるかなと。

数値がどう目標がどうというのは緩く共有しているくらいですが、一番いい刺激になるなあと思っているのは鏡の前で自撮りした自分たちの体の写真を送り合うことです。一緒に筋トレを始めた友達の体が、前と比べて格段に成長していたりすると、自分も負けれられないと心に火がつくこと請け負いです。

まとめ

筋トレを続ける、ということに大切なのはいかにトレーニングすることに対しての心理的なハードルを下げるかだと思っています。周りの人と協力しあうことで、来年も楽しく体を動かしてタイトなジーンズにねじ込める戦うバディを作っていきましょう。

UITableHeaderViewを上端固定する

スクロール時にUITableHeaderViewを上端に固定して、Twitter的な見た目を実現する時にちょっとハマった。

if (self.tableView.contentOffset.y < 0) {
        float offsetY = self.tableView.contentOffset.y;
        CGRect tblFrame = self.tableView.tableHeaderView.frame;
        [self.tableView layoutIfNeeded]; // ポイント
        self.tableView.tableHeaderView.frame = CGRectMake(tblFrame.origin.x, self.tableView.contentInset.top+offsetY, self.tableView.frame.size.width,  self.tableView.frame.size.height);
    }
ポイント

ポイントと雑に書いたところがミソで、AutoLayoutの影響かこれがないとヘッダーは普通にスクロールしてしまった。
レイアウトし直させて、位置を決め直すということをしている。

古いバージョンのpythonとpostgreでDBのデータをxmlに変換して出力した

python2.4 とpostgreを使ってDBのバックアップを取るためにxmlとして出力する必要がありまして、その時のメモです。
方法は二つあって、DOMをメモリ上に全部もってからまとめて吐き出す方法と地道に一つずつ書き出していく方法があります。
小さなDBだったらまとめて吐き出せばいいと思うのですが、今回50万行以上のレコードがあったためそれだとメモリに乗らずに
スワップを使い切りそうでした。(実行してから教えてもらって気づいた・・・。)

以下、実例。

# -*- coding: utf-8 -*-
import datetime
import pgdb
import xml.dom.minidom, codecs
from xml.sax import saxutils


HOST = "localhost"
DATABASE = "sample"
USER = "ayahito"
PASSWORD = ""
FILE_NAME = "backup.xml"

STEP_NUM = 10000


def get_connecter(host, database, user, password):
    connecter = pgdb.connect(
        host=host,database=database,user=user,password=password)
    return connecter


def get_cursor(connecter):
    return connecter.cursor()


def get_count(connecter, tablename):
    cursor = get_cursor(connecter)
    cursor.execute("""
        SELECT COUNT(*) FROM %s;
        """ % (tablename))
    rows = cursor.fetchall()
    count = rows[0][0]
    return count


def get_table_names(connecter):
    cursor = get_cursor(connecter)
    cursor.execute("""SELECT relname AS table_name FROM
        pg_stat_user_tables;""")
    rows = cursor.fetchall()
    rows = [row[0] for row in rows]
    return rows


def get_table_records_and_column_names(connecter, table_name):
    cursor = get_cursor(connecter)
    cursor.execute("SELECT * from %s" % (table_name))
    col_names = [cn[0] for cn in cursor.description]
    col_rows = cursor.fetchall()
    return col_rows, col_names


def get_xml_doc():
    doc = xml.dom.minidom.Document()
    return doc


def create_root(doc):
    root = doc.createElement('root')
    doc.appendChild(root)
    return root

def create_child(doc, parent, elem_name):
    child = doc.createElement(elem_name)
    parent.appendChild(child)
    return child

def append_value_to_elem(doc, elem, value):
    if not isinstance(value, str):
        value = str(value)
    elem.appendChild(doc.createTextNode(value))


def write(doc, file_name):
    f1 = codecs.open(file_name, 'w', 'utf-8')
    doc.writexml(f1)
    f1.close()


def write_root(file_name):
    file_name.write("""<?xml version="1.0" ?><root>""")

def write_end_root(file_name):
    file_name.write("""</root>""")

def write_start_tag(file_name, name):
    file_name.write("<" + saxutils.escape(name) + ">")

def write_end_tag(file_name, name):
    file_name.write("</" + saxutils.escape(name) + ">")


def write_value(file_name, value):
    if (isinstance(value, int) or isinstance(value, float) or
        isinstance(value, long)):
        value = str(value)
    elif (isinstance(value, datetime.datetime) or
            isinstance(value, datetime.date)):
        value = "%s" % (value.isoformat())
    elif isinstance(value, str):
        value = value.decode('utf-8')
    else:
        value = str(value)
    file_name.write(saxutils.escape(value))


def step_execute(f, table_name, connecter):
    records = True
    last_used_id = 0
    while records:
        cursor = get_cursor(connecter)
        cursor.execute(
            "SELECT * from %s where id > %s order by id limit %s" % (
            table_name, last_used_id, STEP_NUM))
        col_names = [cn[0] for cn in cursor.description]
        records = cursor.fetchall()
        write_row(f, records, col_names)
        if records:
            last_record = records[-1]
            last_used_id = last_record[col_names.index("id")]


def write_row(f, records, col_names):
    for record in records:
        write_start_tag(f, "row")
        for col_name, value in zip(col_names, record):
            write_start_tag(f, col_name)
            write_value(f, value)
            write_end_tag(f, col_name)
        write_end_tag(f, "row")


def execute():
    doc = get_xml_doc()
    root = create_root(doc)
    connecter = get_connecter(HOST, DATABASE, USER, PASSWORD)
    table_names = get_table_names(connecter)
    for table_name in table_names:
        table_elem = create_child(doc, root, table_name)
        records, col_names = get_table_records_and_column_names(
            connecter, table_name)
        for record in records:
            row_elem = create_child(doc, table_elem, "row")
            for col_name, value in zip(col_names, record):
                colum_elem = create_child(doc, row_elem, col_name)
                append_value_to_elem(doc, colum_elem, value)
    write(doc, FILE_NAME)


def less_memory_execute():
    connecter = get_connecter(HOST, DATABASE, USER, PASSWORD)
    table_names = get_table_names(connecter)
    f = codecs.open("backup.xml","w","utf-8")
    write_root(f)
    for table_name in table_names:
        write_start_tag(f, table_name)
        if get_count(connecter, table_name) > STEP_NUM:
            step_execute(f, table_name, connecter)
        else:
            records, col_names = get_table_records_and_column_names(
                connecter, table_name)
            write_row(f, records, col_names)
        write_end_tag(f, table_name)
    write_end_root(f)


if __name__ == "__main__":
    less_memory_execute()

メモリに一度に乗らないように決められた行数分だけレコードを取得して
ファイルに書き出しています。定数使ったのでSTEP_NUM書き換えれば一度に取得する値も変えられます。

バックアップサーバからDBサーバにバックアップデータを取得しにいく

バックアップサーバから、DBサーバにアクセスしてMySQLのデータを取ってきてバックアップフォルダに吐く。
dateコマンドはいつも使い方を忘れる。

mysqldump -h dbserver -u dbuser --password=dbpass db | gzip > /home/backupuser/backup/backup_`date +%Y%m%d`.tar.gz

Vimの置換・検索時に大文字小文字を区別して欲しかった。

デフォルトではどうやら区別するらしいのが、おすすめ設定を導入していたところ

見事に区別されなかったので、置換の時だけ一時的に変更したかった。

以下のようにして対応しました。

"大文字小文字を区別する
set noignorecase

"大文字小文字を区別しない
set ignorecase

Outletのweak参照の理由

UIViewControllerに繋いだ時のアウトレットが何で自動で弱参照(weak)になるのか、今日UIKitの書籍読んでいて初めて知りました。

 

以下、である調。

UIViewControllerが管理しているViewのことをコンテンツビューといい、アウトレットで繋がっているものは元々コンテンツビューと強参照で繋がっている。コンテンツビューは画面の表示と対応していて、非表示になった時に開放したりする。コンテンツビューとだけ強参照で繋がっていると、コンテンツビューのメモリ開放のタイミングでアウトレットも一緒に開放される。UIViewControllerとも強参照で繋がっていると、Viewを開放しただけではアウトレットは消えず。メモリ開放を明示的に行わなければいけない。(サブビューで画面上に出したものを消したとき、そのサブビューに紐づいたアウトレットだけメモリが開放されず残っちゃうのでUIViewController側で消す処理を書かなければいけない)

 

 

 というようなことを以下の書籍を読んで勉強中です。

 

 

UIKit徹底解説 iOSユーザーインターフェイスの開発

UIKit徹底解説 iOSユーザーインターフェイスの開発