Python: 初心者がBランク問題を解いていった際に必要だった知識のまとめ

# 背景
C, C# 経験者が、話題になってた Python 学んでおこうかと思い、paiza の問題を構文とか調べながら B ランク問題を解いていった際の備忘録

平均一問／週程度で解いてると、忘れ去ってしまうので、たまにはまとめておかないと、というのが動機

2021/11/25 時点で、B ランク14問 Clear
Pythonだとこれが一番よい結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/e1864533-ec22-e198-c8a1-c2277785caff.png)

2021/1/6 20問目ぐらいで初 1 位 業務で全く使ってないけど 😁
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/3a057aa4-fcdf-273f-a38c-a6682f6a8a1a.png)


# 環境
Python 3.9.6

# Baseとするソース
Base のソースとしてまとめておいて、これを元に開始することで、解答時間内に調べなくてもよくなりつつある感じ
A ランク・・・いつ挑戦しようかは悩み中。実務で使ってないと自信がなかなかつかないですね・・。ほぼ毎回構文とかをネットで調べるので :laughing: 

```python:Base.py
import pandas as pd
import numpy as np
import math
import re

# 読み取り  よくある M N 形式の読み取り
# firstLine = input().rstrip().split(' ')
firstLine = "5 3".rstrip().split(' ')
ValueM = int(firstLine[0])
valueN = int(firstLine[1])
for value in range(ValueM):  # M の数だけループ：starts with 0
    print(value)

# 文字列を一文字ずつ抽出
# for value in list("123"):
    # print(value)

widthNumber = 1
digit = 3
height = 5
width = 4
dataArray = np.zeros((height, width))   # 5x4 を 0 Initialize
for row in range(height):
    for column in range(width):
        dataArray[row][column] = row * (width) + column
        # [[ 0.  1.  2.  3.]
        #  [ 4.  5.  6.  7.]
        #  [ 8.  9. 10. 11.]
        #  [12. 13. 14. 15.]
        #  [16. 17. 18. 19.]]
        # print(dataArray)
#                           1 < 3　の指定で row[1, 2 ]を取得出来る 
for currentRow in np.array([row[1:3] for row in dataArray]):
    print(currentRow)
    # [1. 2.]
    # [5. 6.]
    # [ 9. 10.]
    # [13. 14.]
    # [17. 18.]

# Class の利用例
class line:
    def __init__(self, x0, y0, x1, y1):  # (x0, y0) to (x1, y1) 
        if (x0 > x1):
            self.RightX = int(x0)
            self.LeftX = int(x1)
        else:
            self.RightX = int(x1)
            self.LeftX = int(x0)

        if (y0 > y1):
            self.TopY = int(y0)
            self.BottomY = int(y1)
        else:
            self.TopY = int(y1)
            self.BottomY = int(y0)
        self.IsX = self.RightX != self.LeftX    # 直行線しかないので、X が相違あれば、X軸に平行な線と判断
    
    # lower than
    def __lt__(self, other):        # 降順　昇順なら gt
        return self.x0 < other.x1

def areaValue(lX1: line, lX2: line, lY1: line, lY2: line):
    return 1

# 文字列置換
## 一括
transration = str.maketrans("abcd", "dcba") 
decodedString = "abcdefg".translate(transration)
print(decodedString)
transration = str.maketrans({'a':'AA', 'c':'CC'})
decodedString = "abcdefg".translate(transration)
print(decodedString)
print(" hoge ".strip())
print(" hoge ".lstrip())    # left strip
print(" hogeae ".rstrip(" ae"))    # right strip - 文字列ではなく、文字単体で削除。

# array
values = []
values.append("3")
values.append("10")
values.append("4")
print(values.sort())                   # 昇順
print(values)
values.sort(reverse = True)             # 降順
print(values)
intValues = [int(number, base=10) for number in values]    # 10進として変換
hexValues = [int(number, base=16) for number in values]    # 16進として変換
print(intValues)
print(hexValues)
print(np.amax(intValues))       # 最大値
print(np.average(intValues))    # 平均値

# GroupBy(g=> g).Where(w=> w.Count() == 2)
cards = [1, 2, 5, 8, 5, 2, 2]
groupedValues = {uniqueValue:[inputValue for inputValue in cards if inputValue == uniqueValue] for uniqueValue in unique(cards)}
listPairs = filter(lambda x: len(x[1])==2, groupedValues.items())    # x[0]: Index, x[1]: value(s) 
print(list(listPairs))  
# GroupBy(g=> g).Where(w=> w.Count() == 2) by bandas
df = pd.DataFrame(cards)
grouped = df.groupby([0])
print(grouped.filter(lambda x: x.size == 2))

# 数値演算
print(np.absolute(-7))
print(2 ** 4)   # 2^4
print(2 ** 0.5) # 2^(1/2)
print( np.sqrt(2))  # ↑
print(10 % 3)   # 余り
print(10 // 3)  # 商　整数
print(10 / 3)   # 除
print(round(3.333, 2))   # 小数ｎ桁必要な場合
print(math.ceil(10/3))      # 切り上げ

# 型変換
int("1")
str(1)

# 三角関数
angle = 30 # °
print(np.tan(math.radians(angle)))
print(np.cos(math.radians(angle)))
print(np.sin(math.radians(angle)))

# 正規表現
re.compile(r'\w').search('12ab34')  # 繰り返し使う場合は 保持しておいたほうがいいみたいだけど、普通はキャッシュされるので使うことは少なそう
matches = re.search(r'(\d{2,3})(\w)', 'abc123def24gh5ij')   # match は search wwith r'^'　な感じなのでこれまでの感覚だと search 利用が better
print(matches.group())  # == group(0) 
print(matches.groups())
findAll = re.findall(r'\d{2,3}', 'abc123def24gh5ij')    # 全部拾いたい場合
print(findAll)
for group in findAll:
    print(group)
```

# 補足
> hexValues = [int(number, base=16) for number in values]    # 16進として変換

16進配列を 10進へ変換するときに利用

> transration = str.maketrans("abcd", "dcba") 
> decodedString = "abcdefg".translate(transration)

リストでの置換が出来る。文字列じゃなく、配列とすることで、一文字を複数文字列へ変換することも可能

## round の補足
|方法|概要|補足|
|-|-|-|
|[round](https://docs.python.org/ja/3/library/functions.html?highlight=round#round)|意図通りでない丸めがあることを認識のこと<br>1. 偶数丸め（銀行家丸め）<br>![2021-11-22_09h00_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/ce865bd2-5d2c-da20-b7c9-a7c4298b2b88.png)<br>2. 浮動小数での制限<br>![2021-11-22_09h24_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/88784445-24cc-b39e-45e2-5f594f27e148.png)|-|
|[Decimal.quantize](https://docs.python.org/ja/3/library/decimal.html?highlight=decimal#decimal.Decimal.quantize)|丸めモードに従って丸め。正し、上記の注釈の影響を排除したいなら、演算自体を Decimal にする。金銭や、厳密な制御などに必要だが、通常は脳内 Index 構築程度で。 |[丸めモード](https://docs.python.org/ja/3/library/decimal.html?highlight=decimal#rounding-modes) はここ|

# 最後に
高得点を目指すためには、時間に追われつつも、入出力の制限をちゃんと対処しておくこと
手を抜くと、境界条件で :crossed_swords: 判定されて、大きな減点が入ってしまいますしね。