python Checkio.org Elementaryを解く その3 Q9〜最後

##https://py.checkio.org
参考元。今日も元気


##Q.9 Fizz buzz
あなたは正の整数を受け取って以下を返す関数を書かなくてはいけません:
"Fizz Buzz" その数が3と5で割り切れるとき;
"Fizz" その数が3で割り切れるとき;
"Buzz" その数が5で割り切れるとき; 
その数 それ以外の場合は文字列に変換

入力: ある数、整数
出力: 答え、文字列
事前条件: 0 < number ≤ 1000

```py
def checkio(number):
    #It's main function. Don't remove this function
    #It's using for auto-testing and must return a result for check.

    if number % 15 == 0:
        return "Fizz Buzz"
    elif number % 3 == 0:
        return "Fizz"
    elif number % 5 == 0:
        return "Buzz"
    else:
        return str(number)

if __name__ == '__main__':
    print(checkio())
```

%　で割るだけ。


##Q.10 The Most Numbers
数値の入った配列が与えられる。要素の最大値と最小値の差を出力せよ。空のリストの場合は０を返す。

入力: 任意個の関数パラメータ、数 (整数、浮動小数点数)。
出力: 最大値と最小値の差、数 (整数、浮動小数点数)。
事前条件: 0 ≤ len(args) ≤ 20
all(-100 < x < 100 for x in args)
all(isinstance(x, (int, float)) for x in args)

例：

```py
checkio(1, 2, 3) == 2
checkio(5, -5) == 10
checkio(10.2, -2.2, 0, 1.1, 0.5) == 12.4
checkio() == 0
```

```py
def checkio(*args):
    print(*args)    #*args, argsで出力される値が違う？
                    #タプルの形式で入ってる。タプルに*つけると何が起こる？→後述
    print(args)
    num = list(args)
    box = 0
    ans = 0
    if len(num) == 0:
        ans = 0
    else:
        for i in range(len(num)):
            for j in range(i, len(num)):
                if num[j] > num[i]:
                    box = num[i]
                    num[i] = num[j]
                    num[j] = box
        ans = num[0] - num[-1]
    return ans

if __name__ == '__main__':
    def almost_equal(checked, correct, significant_digits):
        precision = 0.1 ** significant_digits
        return correct - precision < checked < correct + precision
print(checkio(1, 2, 3))
```

問題自体は簡単。リストの並べかえして、最大値-最小値。

`*args`でなんじゃこりゃとちょっとなった。
`*args`を引数に指定すると、(1, 2, 3, 4, 5, ...n)のように任意の数の仮引数をタプルにするようだ。

今回はcheckio(1,2,3)ゆえに*argsを受け取った関数checkioの中で色々試した。
`print(args)`はタプルの形式で出力される。
`(1, 2, 3)`
`print(*args)`だと何か()が消えて、空白が挿入され出力。
`1 2 3`
が、こっちの使いみちがいまいちわからなかった。
`*args.split(" ")`しても例外
`a = *args`　と変数にも代入できない
`[x, y, z] = *args`  と*argsと同サイズのリストに多値代入もできなかった。
なんじゃこりゃ。
ゆえにタプルのargsをlist()に変換した。
作者の意図を何か無視してしまった？わからん。


##Q.11 Even the last
題名がやけにかっこいい。
整数の配列が与えられる。インデックスが偶数の数値を足し算し、その結果とリストの最後を掛け算せよ。空の配列は０を返せ。

入力: 整数のリスト
出力: 結果の数値、整数
例:

```py
checkio([0, 1, 2, 3, 4, 5]) == 30
checkio([1, 3, 5]) == 30
checkio([6]) == 36
checkio([]) == 0
```

```py
def checkio(array):
    """
        sums even-indexes elements and multiply at the last
    """
    ans = 0
    i = 0
    if len(array) == 0:
        return ans
    elif len(array) % 2 == 0:   #last index isn't Even number
        slice = array[:-1]      #index0~index-1を含まないまでスライス
        while i <= len(slice):
            ans += slice[i]
            i += 2
    else:                       #last index is Even number
        while i <= len(array): 
            ans += array[i]
            i += 2
    ans = ans * array[-1]
    return ans

if __name__ == '__main__':
    print(checkio([]))
```

スライスして、足して掛けてだけ。
例外IndexError: list index out of rangeを避け方の問題。list[n]のnがリストを超えるとこの例外が返ってくる。


##Q.11 Secret Message
「賢い人はどこに葉を隠す？その森の中でだ。 しかし森がなかったら彼はどうするのだ？ …彼はそれを隠すために森を育てる」
-- ギルバート・ケイス・チェスタートン

蛇足：
こういうことわざや言葉って、特定の状況にしかそぐわないことも多い。そもそも行動が伴ってない妄想の言葉であることもある。作り話だったり。誇張だったり。話半分に聞くのが良いと思うな。
たまにふと共感して実感するくらいが丁度いい。で、別の状況においてそぐわねーと思うまでセット。プログラミングのコードがあってても、例外は起きるじゃん？
"沈黙は金"のときもあれば"沈黙は汚泥"のときもあるだろうって、言わないのずるくない？"Touch mad and let it turn　into gold"で実は常に金かも。どうだろうね。


英文のテキストが与えられる。その分から大文字だけを抽出して、秘密の暗号を出力せよ。大文字がないなら暗号は空っぽだ。
入力 文字列(unicode) のテキスト
出力 秘密のメッセージの文字列か、空の文字列
例:

```py
find_message("How are you? Eh, ok. Low or Lower? Ohhh.") == "HELLO"
find_message("hello world!") == ""`
```

```py
def find_message(text):
    #str.islower() 小文字の判定
    #str.isupper()　大文字の判定
    str = ""
    for letter in text:
        if letter.isupper():
            str += letter  
    return str
```

すげー簡単。textに対して,isupper()使うだけ。
"."とか" "は自動的にfalse返してくれるから削除する必要もない。
そういやpythonはあらゆる状況で大文字と小文字を区別する。


##Q.12 Three Words
空白で区切られたワードと数をもつ文字列が与えられる。
ワードは文字だけを含んでいる。文字列が連続した３つのワードを含んでいるかチェックする。
つまり、数字を含まない文字列が空白区切りで３つ連続したらTrue。それ以外はFalse

入力: 文字列
出力: ブール型 True or False
事前条件: 入力はワードと数の両方、またはワードのみ、または数のみを含みます。 (文字と数字の両方を含む)混在したワードは存在しません。
例:

```py
checkio("start 5 one two three 7 end") == True
checkio("Hello World hello") == True
checkio("He is 123 man") == False
checkio("1 2 3 4") == False
checkio("bla bla bla bla") == True
checkio("Hi") == False`
```
test:

```py
one two 3 four five 6 seven eight 9 ten eleven 12
one two 3 four 5 six 7 eight 9 ten eleven 12
one two 3 four five six 7 eight 9 ten eleven 12
1231 321 3123 12312 3231 321 312 3123 1231
sda das das dsa adfs dfasd fas
0 qwerty iddqd asdfg
```
コレ以外にもかなりたくさんでコードを確認してる。かききれん。

```py
def checkio(words):
    #replace?1-9
    words = words.split(" ")
    array = []
    for word in words:
        box = word
        array.append(box.replace("1", "").replace("2", "").replace("3", "").replace("4", "").replace("5", "").replace("6", "").replace("7", "").replace("8", "").replace("9", "").replace("0", ""))

    if len(array) < 3:
        return False
    else:
        count = 0
        for i in range(len(array) - 2): 
            for j in range(i, i+3):
                if array[j] == "":
                    count += 1
            if count == 0:
                return True
            count = 0

if __name__ == '__main__':
    print(checkio("one two 3 four five six 7 eight 9 ten eleven 12"))
    print(checkio("0 qwerty iddqd asdfg"))
```

変なところで詰まったが,1-9を全部""で置き換える。リストの内部を３つの連続ずつ検索すればいいだけ。
例文にyou are over 9000ってでてベジータで笑った。
あっちはit'sか。

#####以下。ミスったコード。と五里霧中な過去の自分
何かpythonってwhileのなかでfor文使うのバグるのか？
→　i　の使いすぎミス。
前述コードの最後のelse以降

```py
else:
        num = 0
        count = 0
        while i < (len(array) - 2):
            for i in range(i, i+3):
                if array[i] == "":
                    count += 1
            if count == 0:
                return True
            count = 0
            i += 1
        return False
```

print(checkio("0 qwerty iddqd asdfg"))このときTrueが出てほしいけど、Falseがでる。というかそもそもasdfgをi=1のとき判定してない。でいきなりFalse。わけわからん
↓
意味分かったぁあああ。whileでもi。for i in range()とiで管理してるからだわぁああああ。
forの中の i を j に変えたらいけたぁあああ。
以後気をつける。なんてミスや。


##Q.13 Index Power
正の整数のリストと、数値Nが与えられる。リストのindex[N]の要素のN乗を求めよ。Nが配列の外にあるときは-1を返す

入力: 2つのパラメータ、配列(整数のリスト)とN(整数)。
出力: 結果(整数)
例：

```py
index_power([1, 2, 3, 4], 2) == 9
index_power([1, 3, 10, 100], 3) == 1000000
index_power([0, 1], 0) == 1
index_power([1, 2], 3) == -1
```

```py
def index_power(array, n):
    """
        Find Nth power of the element with index N
    """
    if n >= len(array):
        return -1
    else:
        return array[n] ** n
```

簡単。a ** b でaのb乗が計算できる。


##Q.14 Right to Left
　連続した文字列が与えられる。,で区切られたテキストに結合させる。単語内のrightはleftに変えなきゃならない。
何か問題がどんどん簡単になってくぞ？

input:
連続した文字列がタプルで与えられる
output:
テキストを文字列で出力する
例：

```py
left_join(("left", "right", "left", "stop")) == "left,left,left,stop"
left_join(("bright aright", "ok")) == "bleft aleft,ok"
left_join(("brightness wright",)) == "bleftness wleft"
left_join(("enough", "jokes")) == "enough,jokes"
```

```py
def left_join(phrases):
    """
        Join strings and replace "right" to "left"
    """
    phrases = list(phrases)
    ans = ""
    for word in phrases:
        ans += word.replace("right", "left") + ","
    return ans.rstrip(",")  #rstrip() 末尾から引数以外に当たるまで引数を消す。
```

replace()して、rstrip()で語尾の","を消すだけ。


##Q.15 Digits Multiplication
 正の整数が与えられる。0以外の各桁の積を出せ。
input:
int,正の整数
output:
int,各桁の積
例：

```py
checkio(123405) == 120
checkio(999) == 729
checkio(1000) == 1
checkio(1111) == 1
```
made by bryukhの問題はすっごいeasyな感じ。

int object is not　iterable.
iterateってまだよく分かってない。dive into pythonにまだ教えてもらってないねん。
intだとforの範囲として使えないんだな。

```py
def checkio(number):
    print(number)
    ans = 1
    for i in str(number):
        if int(i) == 0:
            ans *= 1
        else:
            ans *= int(i)
    return ans
```

int object is not　iterable.ゆえに一旦str()してからint()でintに戻して計算。

##Q.16 Number Base
基数（１０進数/radix)や記数法（N進数/Numeral system)の問題。
文字列で表現された正の数と、その基数が与えられる。
これらを１０進数に変換する。しかし、1Aなどは９進数に存在しないものは-1を返せ。

input:
２つの引数。数の文字列。基数の整数
output:
１０進数の整数か-1。

```py
def checkio(str_number, radix):
    #int()
    #try...except...を使う
    try:
        x = int(str_number, radix)
        return x
    except:  #何も例外を記述しないとあらゆる例外でexceptに入る？
        return -1
```

何かTipsがあって、
`int()`の公式説明
https://docs.python.jp/3/library/functions.html#int
`exception()`の公式説明
https://docs.python.jp/3/tutorial/errors.html#exceptions
を読んでくれ。とのことで、読んでからなら解けた。

######・int()
・`int()`には記数法を扱う機能が元々あるみたい。
・より正確に記述すると、`int()`は
`int(x, base=10)`であり、xは`文字列、 bytes インスタンス、 bytearray インスタンスのいずれか`である。baseも指定することができる。
・baseには１０が予め引数として設定されているということがわかった。

######exception
・`try...except　例外名：...`で特定の例外が起きたときにどんな処理を行うか記述できる。
・`try`ブロックで例外が発生した場合は、tryブロックのそれ以降をスッキプし`except`ブロックに入る。
・`try`ブロックで例外が発生しなかった場合は,`except`ブロックをスキップして`try`文の実行を終える。
・`except節`で指定された例外と一致しない場合は、クラスを遡り例外に対する対応を探しに行く。


##Q.17 Absolute sorting
数値を持ったタプルが渡される。絶対値で且つ昇順で並べ替えてください。
preconditon:
リスト内部の数値は一意的である
input:
数値の配列、もしくはタプル。
output:
絶対値で昇順に並び替えられたリストかタプル
例:

```py
checkio((-20, -5, 10, 15)) == [-5, 10, 15, -20] # or (-5, 10, 15, -20)
checkio((1, 2, 3, 0)) == [0, 1, 2, 3]
checkio((-1, -2, -3, 0)) == [0, -1, -2, -3]
```

絶対値かぁ。別に簡単じゃね？0以下なら-1かけるだけだろ？

```py
def checkio(numbers_array):

    num = list(numbers_array)
    print(num)
    for i in range(len(num)):   #len(num) 4
        for j in range(i+1, len(num)):
            #num[i] + or - 
            if num[i] < 0:  #i -
                if num[j] < 0:  #j -
                    if num[j]*-1 < num[i]*-1:   #both -
                        box = num[i]
                        num[i] = num[j]
                        num[j] = box
                else:           #j +
                    if num[j] < num[i]*-1:       #i -, j +
                        box = num[i]
                        num[i] = num[j]
                        num[j] = box
            else:           #i +
                if num[j] < 0:                  #i +, j -
                    if num[j]*-1 < num[i]:
                        box = num[i]
                        num[i] = num[j]
                        num[j] = box
                else:
                    if num[j] < num[i]:         #both +
                        box = num[i]
                        num[i] = num[j]
                        num[j] = box
    return num
```

i - j -
i - j +
i + j -
i + j +
の４つに場合分けして、-のときは*-1するだけ。
numbers_arrayの変数名長くて一回書き直したくらい。


##Q.15 The Most Frequent
made by oduvanの場合は、日本語訳はない。無慈悲。
文字列のsequanceを受ける。最も頻出するStringを求めよ。
Input:
a list of Strings
Output:
a String
Example:

```py
most_frequent([
        'a', 'b', 'c', 
        'a', 'b',
        'a'
    ]) == 'a'
most_frequent(['a', 'a', 'bi', 'bi', 'bi']) == 'bi'
```

```py
def most_frequent(data):
    """
        determines the most frequently occurring string in the sequence.
    """
    print(data)

    #list.index()で数調べて。remove()する
    i = 0
    dict = {}
    while i < len(data):
        dict[data[0]] = data.count(data[0])
        used = data[0]
        for j in range(dict[used]):
            data.remove(used)
    ans = ""
    count = 0
    for key in dict:
        if dict[key] > count:
            count = dict[key]
            ans = key  
    return ans
```


##Q.16 Easy Unpack
与えられたタプルから、３つの要素を含むタプルを作って返す。
first, third and second to the last for the given tuple。index０、index２そして最後から二番目の順番の。

Input: 
A tuple, at least 3 elements long.
Output: 
A tuple.

Example:`

```py
easy_unpack((1, 2, 3, 4, 5, 6, 7, 9)) == (1, 3, 7)
easy_unpack((1, 1, 1, 1)) == (1, 1, 1)
easy_unpack((6, 3, 7)) == (6, 7, 3)
```

```py
def easy_unpack(elements):
    """
        returns a tuple with 3 elements - first, third and second to the last
    """
    array = list(elements)
    return (array[0], array[2], array[-2])
```
負の配列知らなくても、len()から引けばいいだけかな。


##Q.17 Welcome Email by SendGird
https://py.checkio.org/mission/sendgrid-sendone/solve/
Eメールを送ってみよう。
welcome Emailをユーザーに送るfunctionを作る。
関数は(Email, user_name)の２つの引数を取る。
subject(題名)は"Welcome"そして本文は" "Hi, {name}" ({name}はuser_nameで置き換えてね）

Input: 
Two arguments. email and username
Output: 
None. You should send an email. You don’t need to return anything.

ここ参考にしろだってさ。
https://sendgrid.com/docs/Integrate/Code_Examples/v3_Mail/python.html
APIキーを手に入れるのに物理的に２日営業日かかるらしいからこの問題はpass

・format() :{}の中に指定の値を入れられる。
'任意の文字列{}任意の文字列'.format(変数)


##終わりに
Elementarayの問題はこれでおしまい。ちゃんちゃん。
次の難易度はSendGrid。ってあら、最後の問題の難易度はすでにsendgridみたいだ。APIキー手に入らないから問題溶けなくね？

次はちょっとdive into pythonに戻りつつ、次のレベルの問題を解く。そしてprogateにお金払ったの忘れてた。ポテチ10袋分。だからhtml,css,javsscriptに寄り道も有り。


次回のCheckio:
https://py.checkio.org/mission/stressful-subject/


#####備考:バレンタインチョコ
母ありがとう。
２/14はチャーリーとチョコレート工場を思い出す。今日はもう15日ですけど。
チャーリーとチョコレート工場は知っていても、あれに２巻が存在することを知らない人って結構いる。
チョコはウィスキーボンボンはだめなんだ。名前は好きだけど。