読者です 読者をやめる 読者になる 読者になる

ひるあんどんブログ

色々なことに手を出してみるブログ

Secret Message

「賢い人はどこに葉を隠す?その森の中でだ。 しかし森がなかったら彼はどうするのだ? …彼はそれを隠すために森を育てる」

    • ギルバート・ケイス・チェスタートン

郵便を使わずに誰かに秘密のメッセージを送ったことがありますか? あなたは秘密を教えるために新聞を使うことが出来る。 もし誰かがあなたのメッセージを見つけたとしても、その偏執さや偽の海賊理論をはねのけるのは容易い。 秘密のメッセージを隠す最も簡単な方法の一つは大文字を使うことです。これらの秘密のメッセージを探してみましょう。

あなたはテキストの塊を与えられます。一つの単語のすべての大文字を順番に合わせるとテキストが現れます。

例えば text = "How are you? Eh, ok. Low or Lower? Ohhh.", の時、大文字を集めると"HELLO"というメッセージが得られます。

入力 文字列(unicode) のテキスト

出力 秘密のメッセージの文字列か、空の文字列

find_message("How are you? Eh, ok. Low or Lower? Ohhh.") == "HELLO"

find_message("hello world!") == ""



どうやって使われるか これは文字列を扱う単純な練習(反復、認識、連結)です。

事前条件 0 < len(text) ≤ 1000
all(ch in string.printable for ch in text)


def find_message(text):
    """Find a secret message"""
    message = ""
    for x in text:
        if x.isupper(): message += x
        
    return message

if __name__ == '__main__':
    #These "asserts" using only for self-checking and not necessary for auto-testing
    assert find_message("How are you? Eh, ok. Low or Lower? Ohhh.") == "HELLO", "hello"
    assert find_message("hello world!") == "", "Nothing"
    assert find_message("HELLO WORLD!!!") == "HELLOWORLD", "Capitals"


これは大文字をさがして連結すれば良いから、forで文字列をまわしてisupper()で大文字かどうかを判定。
大文字であれば、空文字に対してどんどん連結する。
ひとつも大文字がなければ、空文字をそのまま返す。


一位の人の解答

find_message = lambda text: ''.join(filter(str.isupper, text))

なんと一行だ。
lambdaはわかるとして、joinとは?

str.join(iterable)

    イテラブル iterable 中の文字列を結合した文字列を返します。 iterable に bytes オブジェクトのような非文字列の値が存在するなら、 TypeError が送出されます。要素間のセパレータは、このメソッドを提供する文字列です。

文字列を結合して返すだけなのか。なるほど。

filterは?

filter(function, iterable)

    iterable の要素のうち function が真を返すものでイテレータを構築します。iterable はシーケンスか、反復をサポートするコンテナか、イテレータです。function が None なら、恒等関数を仮定します。すなわち、iterable の偽である要素がすべて除去されます。

    なお、filter(function, iterable) は、関数が None でなければジェネレータ式 (item for item in iterable if function(item)) と同等で、関数が None なら (item for item in iterable if item) と同等です。

    function が偽を返すような iterable の各要素を返す補完的関数は、 itertools.filterfalse() を参照下さい。

くりかえし可能なもの(今回は文字列)に、第一引数におく関数を適用して真だったものを返すのか。逆に偽の場合だけ返す関数もあるのかー。

じゃあ、filterで真のものだけ返してそれをjoinでくっつけるということをしているということか。

知らない組み込み関数がいろいろあるなー。