Python

python Checkio.org Elementaryを解く その2

参考元:https://py.checkio.org/

作ってくれた人に感謝。
昨日の続きのQ.5から。

Q5. 文字列の検索問題

1つの文字列と、2つのmarker(initial markerとfinal marker)が与えられる。2つのマーカーに挟まれた文字列を出力せよ。

注意点:
1. 2つのマーカーは常に等しくない。違いがある
2. initial markerが検索対象の文字列にない場合は文頭からfinal markerまでを出力
3. final markerがない場合はinitial markerから文末までを出力
4. initial も final markerもないなら文全体を返す
5. final markerがinitial markerより前にあるなら ""を返す

basic:
#These "asserts" are used for self-checking and not for testing
assert between_markers('What is >apple<', '>', '<') == "apple", "One symbol"
assert between_markers("<head><title>My new site</title></head>", "<title>", "</title>") == "My new site", "HTML"
assert between_markers('No[/b] hi', '[b]', '[/b]') == 'No', 'No opened'
assert between_markers('No [b]hi', '[b]', '[/b]') == 'hi', 'No close'
assert between_markers('No hi', '[b]', '[/b]') == 'No hi', 'No markers at all'
assert between_markers('No ', '>', '<') == '', 'Wrong direction'

extra:
Pass: between_markers("Never send a human to do a machine's job.","Never","do")
Pass: between_markers("No one",">","<")

上記のこいつらを満たせばいい。

def between_markers(text: str, begin: str, end: str) -> str:
    """
        returns substring between two given markers
    """
    #in はまとまった文字列で、別のまとまった文字列の中を検索できるみたい
        #>>> "cake" in "cake is good"
        #True
    #initialとfinalが1文字か文字列かで場合分けすべき?
    #Neverとか、1つの文字列にたいして,split("Never")と同じ値でsplit()すると["", ""]ってリストが返ってくる。

    begin_idx = None
    end_idx = None
    ans = ""
    letters = []

    words = text.split(" ")
    print(words)
    for word in words:
        if begin in word:
            begin_idx = words.index(word)
        if end in word:
            end_idx = words.index(word)
    print(begin_idx)
    print(end_idx)

    if begin_idx == None and end_idx != None:   #begin is None
        print(111)
        words[end_idx] = words[end_idx].split(end)
        ans = words[end_idx][0]
    elif end_idx == None and begin_idx != None: #end is None
        print(222)
        words[begin_idx] = words[begin_idx].split(begin)
        ans = words[begin_idx][1]
    elif begin_idx == None and end_idx == None: #both begin and end is None
        ans = text
    else:   #both begin and end is not None
        if begin_idx == end_idx:
            for letter in words[begin_idx]: 
                letters.append(letter)  
            if letters.index(begin) < letters.index(end):
                letters.remove(begin)
                letters.remove(end)
                for word in letters:
                    ans += word
            elif letters.index(begin) > letters.index(end):
                ans = ""
        elif begin_idx < end_idx:
            words[begin_idx] = words[begin_idx].split(begin)
            words[end_idx] = words[end_idx].split(end)
            if words[begin_idx][1] == "" and (words[end_idx][0]) == "":
                for i in range(0, 5):
                    if i == begin_idx:
                        ans += words[i][1] + " "
                    elif i == end_idx:
                        ans += words[i][0]
                    else:
                        ans += words[i] + " "
            else:
                for word in words:
                    if word == words[begin_idx]:
                        ans += words[begin_idx][1] + " "
                    elif word == words[end_idx]:
                        ans += words[end_idx][0]
                    else:
                        ans += word + " "
        else:
            ans = ""
    return ans 

    #print(begin in letters) #リストの場合は値をとりださないとだめだ。inに関して
    #remove()とかでリスト内部の空文字を消す方法でもいけそう?
''''
    #上記はinitialとfinalが1文字のときしか有効じゃない。
initialとfinalが2文字以上かつ、同じindex番号上でくっついている場合は…。
例) `<h1><aaa>apple</aaa></h1> inital=<aaa> final=</aaa> split(initial)→["<h1>", "apple<aaa></h1>"]
split(final)→["<h1>", ["apple", "</h1>"]]`。ん?どうすればいいんだ?

split(inital)の場合は、戻り値に対してpop(0)。split(final)ならpop(1)をすればいいのか。
</aaa>apple<aaa> と ""を返すときもなんとかなりそう。
pop(0)した結果、
if words[begin_idx] == "": 
とかの分岐をつければfinalが先で、initialが後の場合でも対応できるはず。
'''
if __name__ == '__main__':
    print('Example:')
    print(between_markers("Never send a human to do a machine's job.","Never","do"))

Q.6 Best Stock

現在の株価が与えられる。どの株がcost moreか調べろ。
input:
辞書の形式。market identifier codeがkey。valueは株価。
output:
A String and market identifier code.

Example:

best_stock({
    'CAC': 10.0,
    'ATX': 390.2,
    'WIG': 1.2
}) == 'ATX'  もっとも高い値段を出力せよってことだ。
best_stock({
    'CAC': 91.1,
    'ATX': 1.01,
    'TASI': 120.9
}) == 'TASI'

Preconditions:前提条件
All the prices are unique.

def best_stock(data):
    # your code here
    #dateって辞書をつかう。
    #辞書の場合はfor loopでkeyを渡す。
    max = 0
    code = ""
    for stock in data:
        if data[stock] > max:
            max = data[stock]
            code = stock
    return code


if __name__ == '__main__':
    print("Example:")
    print(best_stock({
        'CAC': 10.0,
        'ATX': 390.2,
        'WIG': 1.2
    }))

すげー簡単な辞書内部の比較。

Q.7 Popular Words

determine the popularity of certain words in the text.
とある文字列がどれだけtextに出てくるか調べよ。
注意点:
1. textは複数の行と句読点で構成される
2. oneなら"one", "One", "oNe", "ONE"などの類似wordを探す必要がある。つまり大文字と小文字を区別しない。
3. 探すのを求められるwordは小文字で当てられる
4. もし探すwordがtextにない場合は,0を返す。

Input:
The text and the search words array.

Output:
The dictionary where the search words are the keys and values are the number of times when those words are occurring in a given text.
辞書の形式で{"search word1": 出てきた数, ...}

Example:

popular_words('''
When I was One,
I had just begun.
When I was Two,
I was nearly new.
''', ['i', 'was', 'three']) == {
    'i': 4,
    'was': 3,
    'three': 0
}

Pass:
popular_words("\nWhen I was One,\nI had just begun.\nWhen I was Two,\nI was nearly new.\n",["one","two","three"])
Pass:
popular_words("It's flying from somewhere\nAs fast as it can,\nI couldn't keep up with it,\nNot if I ran.",["it's","ran"])

なんかBest Solutionとか答えあわせもできるみたい。

'''文字列'''で改行した文字列を与えることが出来るのか?へー。
なんどもprint()使わなくて良いんだな

>>> print("""
... aaa
... bbb
... ccc
... ddd
... eee
... fff""")

aaa
bbb
ccc
ddd
eee
fff
>>> 
def popular_words(text, words):
    #rstrip()で改行を消せる ←機能しない。原因分かった後述
    #前書いた標準入力のときrstrip()で後ろから消えたのは標準入力の行ごとにrstrip()をしていたから。
    #replace("\n", "") replace(a, b) aをbに返る。←機能した
    #文字列.upper() 文字列を全部大文字にする
    #文字列.lower() 文字列を全部小文字にする
    #辞書に値を追加するには。辞書[存在しないkey_name] = value

    #改行 , . をreplace(value, "")で削除。全部小文字へ
    #wordsをforループでtextにいくつあるか検索。
    text = text.replace("\n", "").replace(",", " ").replace(".", " ").lower()
    text = text.split(" ")
    print("when" in text) #Whenに対して小文字のwhenはfalse
    dict = {}
    count = 0
    for word in words:
        count = text.count(word)
        dict[word] = count
    print(dict)
    return dict


if __name__ == '__main__':
    print("Example:")
    print(popular_words('''
When I was One,
I had just begun.
When I was Two,
I was nearly new.
''', ['i', 'was', 'three']))

    # These "asserts" are used for self-checking and not for an auto-testing
    assert popular_words('''
When I was One,
I had just begun.
When I was Two,
I was nearly new.
''', ['i', 'was', 'three']) == {
        'i': 4,
        'was': 3,
        'three': 0
    }

rstrip()で改行を消せなかったのか、あるいは消せていたのか。
推測だが、消せてはいた。ただ自分の期待する消し方ではなかった。
When I was One,←ここ\n
I had just begun.←ここ\n
When I was Two,←ここ\n
I was nearly new.←ここ\n
この一番最後のnew.のあとの改行\nはおそらく消してくれたのではないだろうか?と考える。

・実際に試す

>>>print(text + "aaa")
When I was One,
I had just begun.
When I was Two,
I was nearly new.
aaa
>>>print(text.rstrip + "aaa")
When I was One,
I had just begun.
When I was Two,
I was nearly new.aaa

おーきーどーきー。

Q.8 Bigger Price

店内で利用できるテーブルが与えられる。データは辞書の形式で与えられる。
最も高い商品を探してください。
第一引数に探す商品数。第二引数に探すための商品データの辞書が与えられます。

input:
int and list of dicts. Each dicts has two keys "name" and "price"

output:
the same as the second Input argument.

Example:

bigger_price(2, [
    {"name": "bread", "price": 100},
    {"name": "wine", "price": 138},
    {"name": "meat", "price": 15},
    {"name": "water", "price": 1}
]) == [
    {"name": "wine", "price": 138},
    {"name": "bread", "price": 100}
]

bigger_price(1, [
    {"name": "pen", "price": 5},
    {"name": "whiteboard", "price": 170}
]) == [{"name": "whiteboard", "price": 170}]

リストの中身を並び替えるだけ。

def bigger_price(limit, data):
    """
        TOP most expensive goods
    """
    #data自体はリスト。data内部の辞書priceを比較。高い順から並び替える。
    #内部のデータを高い順に並べ替え。
    #limitの数だけ取得する
    price = 0
    for i in range(len(data)): #range(4)→0,1,2,3で4回
        for j in range(i, len(data)):
            if data[j]["price"] > data[i]["price"]:
                box = data[i]
                data[i] = data[j]
                data[j] = box
    print(data)
    ans = []
    for i in range(limit):
        ans.append(data[i])
    print(ans)
    return ans
    #辞書をリストにいれて返す

if __name__ == '__main__':
    from pprint import pprint
    print('Example:')
    pprint(bigger_price(2, [
        {"name": "bread", "price": 100},
        {"name": "wine", "price": 138},
        {"name": "meat", "price": 15},
        {"name": "water", "price": 1}
    ]))

    # These "asserts" using for self-checking and not for auto-testing
    assert bigger_price(2, [
        {"name": "bread", "price": 100},
        {"name": "wine", "price": 138},
        {"name": "meat", "price": 15},
        {"name": "water", "price": 1}
    ]) == [
        {"name": "wine", "price": 138},
        {"name": "bread", "price": 100}
    ], "First"

    assert bigger_price(1, [
        {"name": "pen", "price": 5},
        {"name": "whiteboard", "price": 170}
    ]) == [{"name": "whiteboard", "price": 170}], "Second"

一日一歩。
何かやってると別の何かをしたくなるよ。そういう時はちょっと休憩挟んだり、別の何かを無性にしたくなるよ。
この状態でも、何もかもほっぽりだしたくなる気分はたまにくるけど
逆に何もしてない状態がとても長く続くと、何もする気力がなくなるよ。簡単なことさえ面倒くさくなるし、何か始めるのにとてもエネルギーがいるよ。実感がこもってるよ。

明日はdive into pythonに戻ろうか?
コイケヤのうすしお味がこの世から消滅してた。なぜぇ?代わりに出たうましおとやらはうーんコンソメパンチ。
come back うすしお。