ひるあんどんブログ

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

Non-unique Elements 書き直し

def checkio(data):
    #Your code here
    #It's main function. Don't remove this function
    #It's used for auto-testing and must return a result for check.
    result = []
    for x in data:
        if data.count(x) > 1: result.append(x)
        

    #replace this for solution
    return result
def checkio(data):
    #Your code here
    #It's main function. Don't remove this function
    #It's used for auto-testing and must return a result for check.
    return list(filter(lambda x: data.count(x) > 1,data))

二重ループが汚いので、書きなおした。
つまづいたところは、filterメソッドで帰ってくるのは、filterオブジェクトなのでちゃんとリストに変換してから返さなくちゃならないってこと。

Absolute sorting

ある並び替えにチャレンジしてみましょう。ここには特定のルールに従った配列があります。

その配列 (タプル) は様々な数字を持っています。 あなたはそれを並び替かえなければいけません。ただし絶対値で且つ昇順で並べ替えてください. 例えば、(-20, -5, 10, 15)の配列は、次のように並び替えされます: (-5, 10, 15, 20) あなたの関数は、並び替え済みの配列、もしくはタプルを返さなければいけません。

条件: 配列内の数値は(絶対値が)ユニークである。

入力: 数値の配列、もしくはタプル。

出力: 絶対値で昇順に並び替えられた配列かタプル(ジェネレーターではなく)。

追記: あなたの関数の結果は、テストの説明パネルでリストとして表示されます。

例:

checkio*1 == [-5, 10, 15, -20] # or (-5, 10, 15, -20)

checkio*2 == [0, 1, 2, 3]

checkio*3 == [0, -1, -2, -3]



どのように使われるか: 「並び替え」は多くのタスクの一部としてよく現れるので、どのように使うかを知っていると役に立ちます。

条件: len(set(abs(x) for x in array)) == len(array)
0 < len(array) < 100
all(isinstance(x, int) for x in array)
all(-100 < x < 100 for x in array)

def checkio(numbers_array):
    return sorted(numbers_array,key=lambda x: abs(x))

#These "asserts" using only for self-checking and not necessary for auto-testing
if __name__ == '__main__':
    def check_it(array):
        if not isinstance(array, (list, tuple)):
            raise TypeError("The result should be a list or tuple.")
        return list(array)

    assert check_it(checkio((-20, -5, 10, 15))) == [-5, 10, 15, -20], "Example"  # or (-5, 10, 15, -20)
    assert check_it(checkio((1, 2, 3, 0))) == [0, 1, 2, 3], "Positive numbers"
    assert check_it(checkio((-1, -2, -3, 0))) == [0, -1, -2, -3], "Negative numbers"

pythonでソートするにはsortedを使う。sortedには、どんなルールでsortするかを指定することができる。

 sorted(iterable[, key][, reverse])

    iterable の要素を並べ替えた新たなリストを返します。

    二つのオプション引数があり、これらはキーワード引数として指定されなければなりません。

    key は 1 つの引数からなる関数を指定します。これはリストの各要素から比較のキーを取り出すのに使われます: key=str.lower。デフォルト値は None です (要素を直接比較します)。

    reverse はブール値です。True に設定された場合、リストの要素は各比較が反転したように並び替えられます。

lambdaで局所関数を定義して、それを渡しているだけ。

Clear 1位


def checkio(numbers_array):

    """

    The magic of the key :)

    """

    return tuple(sorted(numbers_array, key=abs))

*1:-20, -5, 10, 15

*2:1, 2, 3, 0

*3:-1, -2, -3, 0

Common Words

単語の検査を続けましょう。あなたはコンマで区切られた2つの文字列が与えられます。 それらの文字列に共通するものは何かを探してください。それらの単語は同じ文字列では繰り返しません。

あなたの関数は両方の文字列に出現するすべての単語を探す必要があります。 結果はコンマで区切られた単語群の文字列でアルファベット順である必要があります。

入力 2つの文字列の引数

出力 共通する単語を文字列として出力する

checkio("hello,world", "hello,earth") == "hello"

checkio("one,two,three", "four,five,six") == ""

checkio("one,two,three", "four,five,one,two,six,three") == "one,three,two"


どうやって使われるか ここではあなたは文字列と集合(set)をどのように扱うかを学ぶことができます。 この知識は言語の解析に有用かもしれません。

事前条件
それぞれの文字列は10単語以上は含みません。
すべての単語はコンマで区切られています。
すべての単語は小文字のラテン文字で構成されています。

def checkio(first, second):
    first = first.split(',')
    second = second.split(',')
    set1 = set(first)
    set2 = set(second)
    
    new_set = sorted(set1 & set2)
    
    return (',').join(new_set)

#These "asserts" using only for self-checking and not necessary for auto-testing
if __name__ == '__main__':
    assert checkio("hello,world", "hello,earth") == "hello", "Hello"
    assert checkio("one,two,three", "four,five,six") == "", "Too different"
    assert checkio("one,two,three", "four,five,one,two,six,three") == "one,three,two", "1 2 3"

まずは与えられた文字列をsplitをつかって、カンマごとに区切る。これで、単語のリストができる。

次にこのリストの集合を作成。

2つの集合の、共通部分は&で取り出せる。set関数については長いので、URLだけ貼っておこうっと。

4. 組み込み型 — Python 3.4.3 ドキュメント

演算子はsetだけにしか有効じゃないけど、関数は任意のイテラブルとれるみたいだ。こっちのほうが汎用性は高い。


共通部分は取り出せたので、あとはアルファベット順にソート。

最後に単語をjoinでカンマつけて、くっつけて返す。

おしまい


clear 1位


def checkio(first, second):

    """

    set data type has useful methods.

    """

    first_set, second_set = set(first.split(",")), set(second.split(","))

    common = first_set.intersection(second_set)

    return ",".join(sorted(common))

関数を使っている。ただ、これsecondをsetにする必要ない気がする。イテラブルなら、OKなんだから、second.split(",")だけでおkでは…。


def checkio(first, second):

    same_words = set(first.split(',')).intersection(second.split(','))

    return ','.join(sorted(same_words))

と思ったら、三位の人の解答にあった。やったー。

Number Base

数学の授業の基数(radix)と 記数法(Numeral system)を覚えていますか? それを使って練習してみましょう。 (訳注: 基数は例えば10進数の10のことです。底と呼ばれることもあります。記数法はN進法のことです。この場合Nが基数になります。 詳しくは位取り記数法を参照してください)

あなたには文字列で表現された正の数とその基数が一緒に与えられます。 あなたの関数はこれを10進数に変換しなければいけません。 基数は37より小さく1より大きいです。 このタスクは文字列に数字と文字A-Zを使います。

数が変換できない場合に気をつけてください。 例えば: "1A"は基数9(訳注: 9進数)に変換できません。 このような場合にあなたの関数は-1を返さなければいけません。

ヒント(Tips): あなたはこのタスクを以下を使って簡単に解くことができます。 int()変換と 例外(exception)の処理 (ValueErrorを見ましょう)。

入力: 二つの引数。数の文字列と基数の整数。

出力: 変換された数、整数。

例:

checkio("AF", 16) == 175

checkio("101", 2) == 5

checkio("101", 5) == 26

checkio("Z", 36) == 35

checkio("AB", 10) == -1
どのように使われるか: ここであなたは様々な記数法を使う方法と例外の処理を学ぶでしょう。

事前条件:
re.match("\A[A-Z0-9]\Z", str_number)
0 < len(str_number) ≤ 10
2 ≤ radix ≤ 36

def checkio(str_number, radix):
    try:
        return int(str_number,radix)
    except:
        return -1

#These "asserts" using only for self-checking and not necessary for auto-testing
if __name__ == '__main__':
    assert checkio("AF", 16) == 175, "Hex"
    assert checkio("101", 2) == 5, "Bin"
    assert checkio("101", 5) == 26, "5 base"
    assert checkio("Z", 36) == 35, "Z base"
    assert checkio("AB", 10) == -1, "B > A > 10"
class int(x=0)
class int(x, base=10)

    数値または文字列 x から生成された整数を返します。引数が与えられない場合には 0 を返します。 x が数値である場合は x.__int__() を返します。浮動小数点数については、これは 0 の方へ切り詰めます。

    x が数値でない場合、あるいは base が与えられた場合、 x は基数 base の integer literal で表された文字列、 bytes あるいは bytearray のインスタンスでなければなりません。オプションで、リテラルの前に + あるいは - を (中間のスペースなしで) 付けることができます。また、リテラルは余白で囲むことができます。基数 n のリテラルは 0 から n-1 の数字で構成され、値 10-35 を持つ a から z (または A から Z) を含みます。デフォルトの base は 10 です。許される値は 0 と 2-36 です。基数 2, 8, 16 のリテラルは、オプションでコード中の整数リテラルのように 0b/0B, 0o/0O, or 0x/0X を前に付けることができます。基数 0 はコードリテラルとして正確に解釈することを意味します。その結果、実際の基数は 2, 8, 10, 16 のどれかです。したがって int('010', 0) は有効ではありませんが、 int('010') や int('010', 8) は有効です。

ヒントにもある通り、intを使って変換して、もじ例外が発生したら-1を投げる。おわり

checkioやると、どんどん関数おぼえていくので楽しいです。

clear 1位


def checkio(*a):

    try: return int(*a)

    except ValueError: return -1

例外はちゃんと、なんの例外を投げるかを指定したほうが行儀が良いようだ。たしかに、自分のコードでは全ての例外を同じように処理してしまう。

引数の*aは、任意引数リストというらしい。チュートリアルでは、使うことは少ないとされている。

4.7.3. 任意引数リスト

最後に、最も使うことの少ない選択肢として、関数が任意の個数の引数で呼び出せるよう指定する方法があります。これらの引数はタプル (タプルとシーケンス を参照) に格納されます。可変個の引数の前に、ゼロ個かそれ以上の引数があっても構いません。

def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))

通常このような 可変 パラメタは、関数に渡される入力引数の残りを全て掬い取るために、仮引数リストの最後に置かれます。*args パラメタの後にある仮引数は ‘キーワード専用’ 引数で、位置指定引数ではなくキーワード引数としてのみ使えます。

>>> def concat(*args, sep="/"):
...    return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'

タプルに保存された引数を、アンパックして渡しているんだなぁ。

4.7.4. 引数リストのアンパック

引数がすでにリストやタプルになっていて、個別な固定引数を要求する関数呼び出しに渡すためにアンパックする必要がある場合には、逆の状況が起こります。例えば、組み込み関数 range() は引数 start と stop を別に与える必要があります。個別に引数を与えることができない場合、関数呼び出しを * 演算子を使って書き、リストやタプルから引数をアンパックします:

>>> list(range(3, 6))            # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))            # call with arguments unpacked from a list
[3, 4, 5]

同じやりかたで、** オペレータを使って辞書でもキーワード引数を渡すことができます:

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print("-- This parrot wouldn't", action, end=' ')
...     print("if you put", voltage, "volts through it.", end=' ')
...     print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
    • This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

Binary count

ロボットにとって10進数は不便です。 彼らが"1"を数える必要があるとき、彼らのコンピュータ脳はその数の2進表現で1を数えたいです。 2進数について詳しくはここで読むことができます(訳注:日本語版)。

あなたにはある数が与えられます(正の整数)。 あなたはこれを2進表現に変換して、数の表記の中に1がいくつあるか数えてください。 例えば: 5 = 0b101は2つの1を含んでいます。したがって答えは2です。

ヒント(Tips): このタスクは2つの関数を使って簡単に解くことができます -- binと count。

入力: ある数、正の整数。

出力: 2進形式の1の個数、整数。

例:

checkio(4) == 1

checkio(15) == 4

checkio(1) == 1

checkio(1022) == 9

どのように使われるか: 数を2進数に変換する方法を学びます。コンピュータサイエンスの目的で役に立ちます。

事前条件: 0 < number ≤ 232

def checkio(number):
    data = str(bin(number))
    count = 0
    
    
    count += data.count('1')
    
    return count
    

#These "asserts" using only for self-checking and not necessary for auto-testing
if __name__ == '__main__':
    assert checkio(4) == 1
    assert checkio(15) == 4
    assert checkio(1) == 1
    assert checkio(1022) == 9

組み込み関数binは整数を二進数に変換する。
あとは、文字列に変換して文字列中に部分文字列がいくつ含まれるかを調べることのできるcount関数を使う。
という解き方でときました。

clear一位


checkio=lambda n:bin(n).count('1')

あれ、countは文字列に変換する必要がないのか…。

str.count(sub[, start[, end]])¶(原文)

    [start, end] の範囲に、部分文字列 sub が重複せず出現する回数を返します。オプション引数 start および end はスライス表記と同じように解釈されます。

>>> d = 111111111111111111111111111111100000000000
>>> bin(d).count('1')
63

あら、本当だ。シークエンス型だったら、勝手に変換してくれるのかな。わからない。でも、str.countって書いてあるしなぁ…。
調べてもわからんかった。うーむ。なんでだろう。

>>> e = 5555555555555555555555555555555777777777777777
>>> bin(e).count('5')
0

おや? どうやら、数字一般に適用できるわけではないみたい。この解答は、vekyさんって人が書いたんだけどこの人、変態的なコードかくからなぁ。まぁ、いいや。countは文字列に使うってことにしよう。うん。例外がある以上、危険だし。

Pangram

パングラム (ギリシャ語:παν γράμμα, pan gramma, 「すべての文字」) とはアルファベットのすべての文字が少なくとも一回使われている文です。ひょっとしたらあなたはよく知られているパングラム "The quick brown fox jumps over the lazy dog" をご存知かもしれません。

このミッションでは、私達はラテンアルファベット(A-Z)を使います。 あなたはラテン文字と句読点によるテキストが与えられます。 あなたはその文がパングラムかそうでないかをチェックする必要があります。大文字小文字は関係ありません。

入力 テキストが文字列として与えれられます

出力 文章がパングラムかどうかをブール値で返します

check_pangram("The quick brown fox jumps over the lazy dog.") == True

check_pangram("ABCDEF.") == False



どうやって使われるか パングラムは書体の表示、装置のテスト、手書きや書道やキーボードのタイピング技術を練習するものとして長年使われてきました。

事前条件

all(ch in (string.punctuation + string.ascii_letters + " ") for ch in text)

0 < len(text)

import string

def check_pangram(text):
    text = text.lower()
    alpha = string.ascii_lowercase
    alpha_list = list(alpha)
    
    for x in alpha_list:
        if text.count(x) < 1: return False
        
    
    return True

if __name__ == '__main__':
    # These "asserts" using only for self-checking and not necessary for auto-testing
    assert check_pangram("The quick brown fox jumps over the lazy dog."), "brown fox"
    assert not check_pangram("ABCDEF"), "ABC"
    assert check_pangram("Bored? Craving a pub quiz fix? Why, just come to the Royal Oak!"), "Bored?"

stringライブラリにascii_lowercaseっていう、出題そのまんまの関数があったのでこれをサクッと利用。

ASCII文字の小文字のリストを作って、それをループでまわしてcountで計測。
1個もない文字があった時点で、パングラムではないので、Falseを返す。


Clear 1位

from string import ascii_lowercase

<200b>def check_pangram(text):

    return set(ascii_lowercase).issubset(set(text.lower()))


ライブラリの読み込み方

from string import ascii_lowercase

はstringオブジェクトのascii_lowercaseをローカルなシンボルテーブルに追加しますよって宣言

なので、直接 ascii_lowercaseを呼び出せるようになっている。

setは集合を扱う組み込み関数。
8.7. sets — ユニークな要素の順序なしコレクション — Python 2.7ja1 documentation



s.issubset(t) s <= t s のすべての要素が t に帰属していれば真を返す

とのこと。

スマートだなぁ。


speedly

from string import ascii_lowercase

<200b>def check_pangram(text):

    return all(letter in text.lower() for letter in ascii_lowercase)


そうだ。どっかで、allって関数をみたけど、使い道までは知らなかった。確かに題意まんまの関数だ。返り値もブールだし。

all(iterable)

    iterable の全ての要素が真ならば (もしくは iterable が空ならば) True を返します。以下のコードと等価です:

    def all(iterable):
        for element in iterable:
            if not element:
                return False
        return True

any(iterable)

    iterable のいずれかの要素が真ならば True を返します。iterable が空なら False を返します。以下のコードと等価です:

    def any(iterable):
        for element in iterable:
            if element:
                return True
        return False

for ループが汚くなってきたので。

map, reduce, filterによるシーケンス操作 » Python Snippets

forループで何度もまわすのも、あんまりきれいじゃないなー。と思っていたら、こんな記事をみつけました。便利な関数があるんだな。