Python
chekio

python checkio.orgのElementaryレベルを解いてみる その1

checkioを解いてみる

選ぶのはpython。javascriptは無知。ゴー。
ステージhomeを選ぶもヘブン状態。
ビギナーはElementary行けばいくといいぜ!!と最初のチュートリアルっぽいので言ってたのを思い出し(というか、最初はHomeかElementary:小学生!しか選べない)。Elementaryと握手。
日本語のサポートなんてないですやん。

1.引数でうけたnameとageをprint()の中の文字列に+で結合させるだけ。

print("文字列" + name + "文字列" + age + "文字列")
英語のサイトだから変数の前後の文字列にスペースで空白を作らないと通らなかったくらい。

2.引数textの最初の文字が小文字なら大文字に。textの最後尾に.がないなら.をつけるって問題。
def correct_sentence(text: str) -> str:
    """
        returns a corrected sentence which starts with a capital letter
        and ends with a dot.
ここdocstringってやつだな。dive into pythonで知ってるぞ。確か__doc__で閲覧できるんやぞ。属性とかいうやつや。
    """
    # your code here
    letters = []
    for letter in text:
        letters.append(letter)    
    letters[0] = letters[0].upper()
    if letters[-1] != ".":
        letters.append(".")
    text = ""
    for letter in letters:
        text += letter
    return text


if __name__ == '__main__':
    #print("Example:")
    #print(correct_sentence("greetings, friends"))

    # These "asserts" are used for self-checking and not for an auto-testing
    #assert correct_sentence("greetings, friends") == "Greetings, friends."
    #assert correct_sentence("Greetings, friends") == "Greetings, friends."
    #assert correct_sentence("Greetings, friends.") == "Greetings, friends."
    #assert correct_sentence("hi") == "Hi."
    print(correct_sentence("hello"))

調べたらstr.capitalize(): 先頭の一文字を大文字、他を小文字にする。なんてのが出た。
capitalize:~を大文字で書く(始める)・資本化する。利用する。
最後に . のあるかないかをリスト以外で調べる方法がわからんかった。だから試しにcapitalize()つかったけど対して変わらんコードになった。悲しみ。大文字、小文字入り乱れたtextなら断然capitalize()なんだろうな。

3. 文字列からfirst wordを抽出。
  1. ピリオド.や,が文字列にある。1つの単語の文字列の中に.があったら.以降の文字を消す。
  2. 文字列はletter or . or 空白で始まる。
  3. 'は1つの単語内に含んで良い。
  4. The whole text can be represented with one word and that's it. 答えは1 wordってことだと思う。
Example:

first_word("Hello world") == "Hello"
first_word("greetings, friends") == "greetings"
first_word("Don't speak... I know just what you're saying") == "Don't"
first_word("Hello.World") == "Hello"
def first_word(text: str) -> str:
    """
        returns the first word in a given text.
    """
    # your code here
    text = text.split(" ")
    words = [""]  #words[0]がnoneだと文字列と結合できない
    chars = []
    count = 0

    print(text)
    for char in text[0]:
        chars.append(char)
        if  chars[0] == ".":
            if count == 0:
                text.pop(chars.index(".")) 
                count = 1 #...で3回pop()を防ぐ
        elif "." in chars:
            if chars[0] != "" and chars[0] != " ":
                #スライスする
                text[0] = ""
                for word in chars[0:chars.index(".")]:
                    text[0] += word          
    for word in text:
        if word == "":
            text.remove("")

    chars = []  #ここHello World Hello
    for word in text[0]:
        chars.append(word)
        if chars[-1] == ",":
            chars.pop(-1)
    for i in range(len(chars)):
        words[0] = words[0] + chars[i]
    return words[0]
#Don't speak... I know just what you're saying
#Hello.World これそのまま返せば良いのか?
# .以降を削除する
#right result: "Hello"


if __name__ == '__main__':
    print("Example:")
    print(first_word("Hello World"))

    # These "asserts" are used for self-checking and not for an auto-testing
    assert first_word("Hello world") == "Hello"
    assert first_word(" a word ") == "a"
    assert first_word("don't touch it") == "don't"
    assert first_word("greetings, friends") == "greetings"
    assert first_word("... and so on ...") == "and"
    assert first_word("hi") == "hi"
    print("Coding complete? Click 'Check' to earn cool rewards!")
4. 文字列から文字を検索する問題

文字列2つが与えられて、 have to find an index of the second occurrence of the second string in the first oneする。
2個目の引数が、1個目の文字列の中で2回目に発生するindexを調べろ。

Input two Strings
Output int or None

Example:

second_index("sims", "s") == 3
   2回目のsの場所は、index番号3
second_index("find the river", "e") == 12
   2回めのeの場所は、index番号12。つまり" "もindexに含む。
second_index("hi", " ") is None
   ない場合が Noneを返す。
def second_index(text: str, symbol: str):
    """
        returns the second index of a symbol in a given text
    """
    # your code here
    letters = []
    for letter in text:
        letters.append(letter)
    #a_list.index(value, index_num) valueの場所を返す
    print(letters)
    count = 0
    if letters.count(symbol) >= 2: #最初symbolがあるかinで判定してたけど、symbolが1回しか出ない場合はNoneを返す必要があるから変更。
        while count < 2:
            if count == 0:
                index_number = letters.index(symbol)
            else:
                index_number = letters.index(symbol, index_number+1)
            count += 1
    else:
        index_number = None
    return index_number


if __name__ == '__main__':
    print('Example:')
    print(second_index("sims", "s"))

    # These "asserts" are used for self-checking and not for an auto-testing
    assert second_index("sims", "s") == 3, "First"
    assert second_index("find the river", "e") == 12, "Second"
    assert second_index("hi", " ") is None, "Third"
    assert second_index("hi mayor", " ") is None, "Fourth"
    assert second_index("hi mr Mayor", " ") == 5, "Fifth"
    print('You are awesome! All tests are done! Go Check it!')
5. 文字列の検索問題 ※今現在迷走中。

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より前にあるなら ""を返せ。

Input: 
Three arguments. All of them are strings. The second and third arguments are the initial and final markers.

Output: 
A string.

Example:
between_markers('What is >apple<', '>', '<') == 'apple'
between_markers('No[/b] hi', '[b]', '[/b]') == 'No'
def between_markers(text: str, begin: str, end: str) -> str:
    """
        returns substring between two given markers
    """
    # your code here
    # use  in  function
    #in はまとまった文字列で、別のまとまった文字列の中を検索できるみたい
    '''
    >>> "<title>" in "<head><title>My new site"
    True
    '''
    #initialとfinalが1文字か文字列かで場合分けすべき
    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)  #これだめだ。beginとendが1文字のときしか有効じゃない
            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 = ""
        #多分値のn中にinitialとfinalがあるならsplitって書くべき?
        elif begin_idx < end_idx:
            print(111)
            words[begin_idx] = words[begin_idx].split(begin)
            words[end_idx] = words[end_idx].split(end)
            print(words[begin_idx][1])
            print(words[end_idx][0])
            for word in words:
                if word == words[begin_idx]:
                    ans += words[begin_idx][1] + " "
                elif word == words[end_idx]:
                    ans += words[end_idx][0]
                    break
                    print(12345)
                else:
                    ans += word + " "
        else:
            ans = ""
    return ans 
    #print(begin in letters) #リストの場合は値をとりださないとだめだ。inに関して
#Fail:between_markers("Never send a human to do a machine's job.","Never","do")
#Your result:" send a human to  a machine's job. "
#Right result:" send a human to "
if __name__ == '__main__':
    print('Example:')
    print(between_markers("Never send a human to do a machine's job.","Never","do"))
    '''
    # These "asserts" are used for self-checking and not for testing
    assert between_markers('What is >apple<', '>', '<') == "apple", "One sym"
    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 <hi>', '>', '<') == '', 'Wrong direction'
    print('Wow, you are doing pretty good. Time to check it!')

    '''

?.
リスト内部のすべての値に対して、それぞれbeginのin
endのin検索を行う。inがTrueのindexを記録で残しておく。
beginのindexとendのindexを比較。

?.
rstrip("")の中にない文字列に当たるまで削除
この問題に対してあんまうまく機能しない

?.
ex = words[begin_idx].split(begin)
initialが別の文字列とくっついている場合はこれだとけっこううまく切れる。
ただ、("Never send a human to do a machine's job.","Never","do")の場合上手くいってない。

そもそも今の記述だと、splitでリストが作られないから。for word in words: がwordsの最後まで繰り返しちゃってる。
output: 現在
send a human to a machine's job.
output: ほしいほう
send a human to  まで
・つまり、splitするべきか、しないべきかをif文で分岐すればいい。

蛇足:

https://utaten.com/lyric/%E5%A4%A7%E6%A7%BB%E5%94%AF%28%E5%B1%B1%E4%B8%8B%E4%B8%83%E6%B5%B7%29/Radio+Happy/

歌の歌詞がほしくて適当に出たサイトでコピペしようとした。いつも通りcromeでjavascriptを無効にすればコピペできるやろ?と鼻で笑ってたらなぜかできぬ。
ぬっ?!調べたらCSS3でテキストのドラッグを禁止できるらしい。なるほど。CSS3を無効化する拡張機能もある。俺は笑った。つまりはそういうことだった。別のサイトからコピペした。