ベスパリブ

プログラミングを主とした日記・備忘録です。ベスパ持ってないです。

AtCoderSort

オブジェクト群を何かの値でソートしたいとき、それはともかくAtCoderのレートで先にソートするソート手法。

コード

# coding: utf-8
class Person():
    
    def __init__(self, rate, height, age, name):
        self.rate = rate      # レート
        self.height = height  # 身長
        self.age = age        # 年齢
        self.name = name      # 名前


def AtCoderSort(p, key, key_reverse=False):
    """ 
    (1) ソートしたい属性(key)を指定する
    (2) レートの高い順にソートする
    (3) レートが等しい場合、(1)で指定した属性でソートする
    """
    from operator import attrgetter
    p = sorted(p, key=attrgetter(key), reverse=key_reverse)
    return sorted(p, key=lambda person: person.rate, reverse=True)


def solve():
    N = 5
    p = [None] * N
    p[0] = Person(1700, 170, 17, "Alice")
    p[1] = Person(1000, 170, 18, "Bob")
    p[2] = Person(2000, 150, 17, "Carol")
    p[3] = Person(2800, 160, 17, "Eve")
    p[4] = Person(1000, 150, 17, "Frank")

    print("--ソート前--")
    for i in range(N):
        print("{}, {}, {}, {}".format(p[i].rate, p[i].height, p[i].age, p[i].name))
    
    print("--背の小さい順でAtCoderSortする--")
    sorted_p = AtCoderSort(p, "height")
    for i in range(N):
        print("{}, {}, {}, {}".format(sorted_p[i].rate, sorted_p[i].height, sorted_p[i].age, sorted_p[i].name))

    print("--年齢が高い順でAtCoderSortする--")
    sorted_p = AtCoderSort(p, "age", key_reverse=True)
    for i in range(N):
        print("{}, {}, {}, {}".format(sorted_p[i].rate, sorted_p[i].height, sorted_p[i].age, sorted_p[i].name))
    

if __name__ == "__main__":
    solve()

結果

--ソート前--
1700, 170, 17, Alice
1000, 170, 18, Bob
2000, 150, 17, Carol
2800, 160, 17, Eve
1000, 150, 17, Frank
--背の小さい順でAtCoderSortする--
2800, 160, 17, Eve
2000, 150, 17, Carol
1700, 170, 17, Alice
1000, 150, 17, Frank
1000, 170, 18, Bob
--年齢が高い順でAtCoderSortする--
2800, 160, 17, Eve
2000, 150, 17, Carol
1700, 170, 17, Alice
1000, 170, 18, Bob
1000, 150, 17, Frank

参考URL

B: AtCoderでじゃんけんを - AtCoder Regular Contest 048 | AtCoder

リストの要素がクラスオブジェクトの場合のソート(Python)

リストの要素がクラスオブジェクトの場合に、そのオブジェクトのメンバ変数に対してソートをしたい。

クラスに対するソート(と言ったら語弊があるけど)。

やりたいこと

class Person():
    
    def __init__(self, _id, height, name):
        self._id = _id
        self._height = height
        self._name = name

def solve():
    N = 5
    p = [None] * N
    p[0] = Person(5, 160, "うえだ")
    p[1] = Person(2, 140, "いいだ")
    p[2] = Person(4, 140, "えのもと")
    p[3] = Person(1, 150, "あすのざか")
    p[4] = Person(3, 160, "おおの")

    # このとき、pをPersonのid順などでソートしたい

def __name__ == "__main__":
    solve()

コード

# coding: utf-8
class Person():
    
    def __init__(self, _id, height, name):
        self._id = _id
        self._height = height
        self._name = name
        self.latest_me = None # 最近振った目の数

    @property
    def id(self):
        return self._id
    
    @property
    def height(self):
        return self._height
    
    @property
    def name(self):
        return self._name
    
    def toss_dice(self):
        """ 1~6の目のサイコロを振り、出た目の数を返す """
        import random
        self.latest_me = random.randrange(1, 7)
        return self.latest_me


def sort_height(p, N):
    print("--背の順でソートする--")

    # lambdaを使う場合
    sorted_p = sorted(p, key=lambda person: person.height)

    # operator.attrgetterを使う場合(結果はlambdaを使った場合と同じ)
    from operator import attrgetter
    sorted_p = sorted(p, key=attrgetter("height"))

    for i in range(N):
        print("{}, {}, {}".format(sorted_p[i].id, sorted_p[i].height, sorted_p[i].name))


def sort_height_and_id(p, N):
    print("--背の順でソートし、かつ、idが若い順にソートする(身長が同じ人はidが若い順に並ぶ)--")
    
    from operator import attrgetter
    sorted_p = sorted(p, key=attrgetter("height", "id"))

    for i in range(N):
        print("{}, {}, {}".format(sorted_p[i].id, sorted_p[i].height, sorted_p[i].name))


def sort_dice(p, N):
    print("--サイコロを振り、出た目の数でソートする(実行するたびに変わる)--")
    
    # lambdaを使う場合
    sorted_p = sorted(p, key=lambda person: person.toss_dice())
    
    # operator.methodcallerを使う場合(結果はlambdaを使った場合と同じ)
    from operator import methodcaller
    sorted_p = sorted(p, key=methodcaller("toss_dice"))

    for i in range(N):
        print("{}, {}, {} : D{}".format(sorted_p[i].id, sorted_p[i].height, sorted_p[i].name, sorted_p[i].latest_me))


def solve():
    N = 5
    p = [None] * N
    p[0] = Person(5, 160, "うえだ")
    p[1] = Person(2, 140, "いいだ")
    p[2] = Person(4, 140, "えのもと")
    p[3] = Person(1, 150, "あすのざか")
    p[4] = Person(3, 160, "おおの")

    # 単純に表示する
    for i in range(N):
        print("{}, {}, {}".format(p[i].id, p[i].height, p[i].name))
    
    # 背の順でソート
    sort_height(p, N)

    # 背の順でソートし、かつ、idが若い順にソートする(身長が同じ人はidが若い順に並ぶ)
    sort_height_and_id(p, N)

    # サイコロを振り、出た目の数でソートする(実行するたびに変わる)
    sort_dice(p, N)

if __name__ == "__main__":
    solve()

↓結果

5, 160, うえだ
2, 140, いいだ
4, 140, えのもと
1, 150, あすのざか
3, 160, おおの
--背の順でソートする--
2, 140, いいだ
4, 140, えのもと
1, 150, あすのざか
5, 160, うえだ
3, 160, おおの
--背の順でソートし、かつ、idが若い順にソートする(身長が同じ人はidが若い順に並ぶ)--
2, 140, いいだ
4, 140, えのもと
1, 150, あすのざか
3, 160, おおの
5, 160, うえだ
--サイコロを振り、出た目の数でソートする(実行するたびに変わる)--
2, 140, いいだ : D1
3, 160, おおの : D1
5, 160, うえだ : D3
4, 140, えのもと : D3
1, 150, あすのざか : D4

おまけ

参考URL:

docs.python.org

海底ケーブルマップがすごい

Django GirlsのREADMEを読んでいて、インターネットの仕組みの項目を読んでいた。

そこに海底ケーブルマップのサイトのリンクがあった。

Submarine Cable Map

すごい。色々すごいけど、志摩市の海底ケーブルの本数がすごい。志摩スペイン村しか知らなかったのに。

オホーツク海のケーブルや、クック諸島にぽつーんとケーブル引かれてるのが見てて面白い。

海底ケーブルって途方がなさすぎて全然イメージできないんですけど、こんなに張られてたんですねぇ。あと地下鉄感がすごい。

f:id:takeg:20190305172520p:plain
志摩の海底ケーブル

f:id:takeg:20190305172551p:plain
オホーツクの大三角形

f:id:takeg:20190305172618p:plain
太平洋にインターネットを届けている

ラズパイでgpartedを実行、"e2fsck cannot continue aborting is mounted"エラー

Raspbian用のSDカードの容量を小さくしたかった。

以前にもやったので、その方法を備忘録として残していました。試行錯誤の結果、以下の記事のまんまやればよいことがわかりました。

qiita.com

で、やってたらエラーが起きました。エラーの詳細を読むと、以下のような感じのことが書いてありました。

e2fsck cannot continue aborting is mounted

/dev/sda2 is mounted

/dev/sda2をアンマウントしてるのにおかしいなーと思ってたんですが、小一時間悩んで理由がわかりました。

私は以下のような構成でやっていました。

  • ラズパイ(起動中。gpartedを実行する。コピー元のSDカードでもある)
  • コピー先のSDカードをUSBに挿す

これではラズパイは起動中なので実際にはアンマウントできていないのが原因でした(たぶん)。

本当に必要な構成は、

  • ラズパイ(起動中。gpartedを実行する)
  • コピー元のSDカードをUSBに挿す
  • コピー先のSDカードをUSBに挿す

でした。

まあ記事をちゃんと読むとそう書いてあるんですけど、以前にやったことあったので適当に流し読みしてしまっていました。気を付けよう。

(SDカードのリーダライタが大きくて、ラズパイのUSBにそのまま2つ挿せなくて延長ケーブルが必要になって面倒くさかった)

Pythonの__file__は、対話モードで実行するとエラーになる

Pythonで、ファイル名を出力してくれる__file__は、対話モードで実行するとエラーになります。

> python
Python 3.7.1 (default, Dec 10 2018, 22:54:23) [MSC v.1915 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.

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

対話モードなので、ファイルなんてないので当然といえば当然なエラーでしょうか。

ファイルで実行するときちんと出力してくれます。

# sample.py
import os

print(__file__)

a = os.path.dirname(os.path.abspath(__file__))
print(a)
a = os.path.dirname(os.path.abspath("__file__"))
print(a)
> python sample.py
sample.py
C:\Users\XXXX\workspace
C:\Users\XXXX\workspace

Bitbucketでブランチのブランチタイプを変更する

Bitbucketで、masterブランチのブランチタイプ(Branch type)がMAINかつDEVELOPMENTになっていたので、developブランチをDEVELOPMENTにしたいという話です。

f:id:takeg:20190131152325p:plain
masterブランチがMAINかつDEVELOPMENT

設定 > Branching model で、Development branchを変更して、保存します。

f:id:takeg:20190131152408p:plain
Deveropment branchの変更

ブランチ画面に行き、ブランチタイプの変更ができていることを確認します。

f:id:takeg:20190131152704p:plain
developブランチがDEVELOPMENT

ブランチタイプの説明は以下の公式に詳しく書いてあります。

ja.confluence.atlassian.com

はてなブログをHTTPS化した

私のはてなブログHTTPSじゃなくて、「いつになったらはてなHTTPS対応してくれるんだろーー~~~~~~~~~~ばなな」って口を開けて待ってたんですが、普通に公式からアナウンスがありました。

help.hatenablog.com

移行方法

ダッシュボードから設定画面にアクセスし、「変更する」を選択してください。

ワンクリックでHTTPS化できました。はてなさんありがとう。