Python文法～初級から中級～

# 目次
[はじめに](#はじめに)  
[コメント文](#コメント文)  
[Pythonの型](#Pythonの型)  
[数値計算](#数値計算)  
[論理演算子](#論理演算子)
[比較演算子](#比較演算子)
[リスト](#リスト)  
[タプル](#タプル)  
[辞書](#辞書)  
[集合](#集合)  
[for文](#for文)  
[if文](#if文)  
[while文](#while文)  
[enumerate関数](#enumerate関数)  
[zip関数](#zip関数)  
[関数](#関数)  
[ジェネレーター](#ジェネレーター)  
[内包表記](#内包表記)  
[ラムダ](#ラムダ)  
[クロージャー](#クロージャー)  
[デコレーター](#デコレーター)  
[例外処理](#例外処理)  
[おわりに](#おわりに)  

# はじめに
ここでは、Pythonで使用される基本的なデータ構造や文法について説明します。ここでは実際にコードを入力した後の出力結果まで記載しますがもしご自身で結果を確認したい場合はGooogleColaboratoryやJupyterNotebookをご利用すればよいかと思います。
個人的にはGooogleColaboratoryのほうがGoogleアカウントさえ持っていればすぐに始められるためおすすめです。

# コメント文
コードの可読性を高めるためのコメント文の書き方について学びます。

```py:Python
#ハッシュ文字から行末までコメントを書けます
#コメントは実行されません
```

# Pythonの型
Pythonの基本的なデータ型（整数、浮動小数点数、文字列など）について説明します。
型を確かめたいときにはtype()を使い、実行結果を見たいときにはprint()関数の中に入れます。
```py:Python
print(type("Hello World"))
print(type(20))
print(type(20.5))
print(type(True))
```

```:outcome
<class 'str'>
<class 'int'>
<class 'float'>
<class 'bool'>
```
# 数値計算
数値計算に使用される基本的な演算や関数について学びます。

```py:Python
#足し算
print(1+2)
#引き算
print(5-2)
#掛け算
print(3*5)
#割り算
print(10/2)
#余り
print(18%7)
#べき乗
print(4**3)
#商
print(5//2)
```
```:outcome
3
3
15
5.0
4
64
2
```
# 論理演算子
論理演算子（and, or, not）を使用して、条件式を組み合わせたり反転させたりする方法を説明します。

```py:Python
a=1
b=3
print(a<b and b<2)
print(a<b or b>2)
print(not a==b)
```

```:outcome
False
True
True
```

# 比較演算子
比較演算子は、値を比較するために使用される演算子で、結果として真（True）または偽（False）を返します。
```py:Python
a=1
b=2
print(a==b)
print(a!=b)
print(a>b)
print(a>=b)
print(a<b)
print(a<=b)
```

```:outcome
False
True
False
False
True
True
```

# リスト
リストは、順序付きの変更可能なコレクションです。重複する要素を持つことができます。

```py:Python
sample_list= [1,2,3,4,5,6,7]
print(sample_list)
print(sample_list[0])
print(sample_list[1])
print(sample_list[2])
#変更
sample_list[1]=100
print(sample_list)
#追加
sample_list.append(100)
print(sample_list)
#削除
sample_list.remove(1)
print(sample_list)
sample_list.pop(0)
print(sample_list)
#挿入
sample_list.insert(0,100)
print(sample_list)
#リストの長さ
print(len(sample_list))
#ソート
sample_list.sort()
print(sample_list)
#逆順
sample_list.reverse()
print(sample_list)
```
```:outcome
[1, 2, 3, 4, 5, 6, 7]
1
2
3
[1, 100, 3, 4, 5, 6, 7]
[1, 100, 3, 4, 5, 6, 7, 100]
[100, 3, 4, 5, 6, 7, 100]
[3, 4, 5, 6, 7, 100]
[100, 3, 4, 5, 6, 7, 100]
7
[3, 4, 5, 6, 7, 100, 100]
[100, 100, 7, 6, 5, 4, 3]
```

# タプル
タプルは、順序付きの変更不可なコレクションです。リストに似ていますが、要素の変更ができません。

```py:Python
sample_tuple=(1,2,3,4,5,6,7)
print(sample_tuple)
print(sample_tuple[0])
print(sample_tuple[1])
print(sample_tuple[2])
##変更
#sample_tuple[1]=100
#print(sample_tuple)
#これを実行するとエラーになります
```
```:outcome
(1, 2, 3, 4, 5, 6, 7)
1
2
3
```
# 辞書
辞書は、キーと値のペアを持つ変更可能なコレクションです。キーはユニークでなければなりません。
```py:Python
sample_dict = {'A':100,'B':200,'C':300}
print(sample_dict)
print(sample_dict['A'])
print(sample_dict['B'])
print(sample_dict['C'])
#key
print(sample_dict.keys())
#value
print(sample_dict.values())
#両方
print(sample_dict.items())
#追加
sample_dict['D']=400
print(sample_dict)
#変更
sample_dict['A']=1000
print(sample_dict)
#削除
sample_dict.pop('A')
print(sample_dict)
del sample_dict['D']
print(sample_dict)
```
```:outcome
{'A': 100, 'B': 200, 'C': 300}
100
200
300
dict_keys(['A', 'B', 'C'])
dict_values([100, 200, 300])
dict_items([('A', 100), ('B', 200), ('C', 300)])
{'A': 100, 'B': 200, 'C': 300, 'D': 400}
{'A': 1000, 'B': 200, 'C': 300, 'D': 400}
{'B': 200, 'C': 300, 'D': 400}
{'B': 200, 'C': 300}
```
# 集合
集合は、順序がなく、重複しない要素のコレクションです。数学的な集合と同様の操作ができます。
```py:Python
sample_set = {1,1,2,3,4,5,3,6,7}
print(sample_set)
#削除
sample_set.remove(1)
print(sample_set)
#追加
sample_set.add(10)
print(sample_set)
print('---------------------------------')
#集合演算
a = set('abracadabra')
b = set('alacazam')
print(a)
print(b)
#差集合 :aに含まれるがbには含まれない文字を返す
print(a - b)
#和集合 :aまたはbのどちらかに含まれるすべての文字を返す
print(a | b)
#積集合 :両方の集合に含まれる文字を返す
print(a & b)
#対称差集合 :aまたはbのどちらか一方にのみ含まれる文字を返す
print(a ^ b)
```
```:outcome
{1, 2, 3, 4, 5, 6, 7}
{2, 3, 4, 5, 6, 7}
{2, 3, 4, 5, 6, 7, 10}
---------------------------------
{'r', 'd', 'b', 'c', 'a'}
{'m', 'l', 'c', 'z', 'a'}
{'d', 'r', 'b'}
{'r', 'd', 'm', 'l', 'b', 'c', 'z', 'a'}
{'c', 'a'}
{'r', 'b', 'd', 'm', 'z', 'l'}
```

# for文
for文を使って、反復処理を行う方法について説明します。
```py:Python
words ='Python'
for word in words:
  print(word)
```
```:outcome
P
y
t
h
o
n
```
# if文
条件に基づいて異なる処理を行うif文の使い方について説明します。
```py:Python
sample = [1,2,3,4,5]
if 3 in sample:
  print('3はsampleに含まれています')
else:
  print('3はsampleに含まれません')

print('---------------------------------')

if 6 in sample:
  print('6はsampleに含まれています')
else:
  print('6はsampleに含まれません')
```
```:outcome
3はsampleに含まれています
---------------------------------
6はsampleに含まれません
```
# while文
条件が真である間、処理を繰り返すwhile文の使い方について説明します。
```py:Python
a = 0
while a < 4:
  print(a)
  a += 1
print('---------------------------------')
#break文：処理の強制終了
b = 0
while True:
  print(b)
  b += 1
  if b >= 4:
    break
print('---------------------------------')
#continue文：この後の処理をスキップする
c = 0
while c < 5:
  c += 1
  if c == 3:
    continue
  print(c)
```
```:outcome
0
1
2
3
---------------------------------
0
1
2
3
---------------------------------
1
2
4
5
```
# enumerate関数
リストを反復処理する際にインデックスを取得するenumerate関数について説明します。
```py:Python
fruits = ['apple', 'banana', 'cherry']

for index, fruit in enumerate(fruits):
    print(index, fruit)
```
```:outcome
0 apple
1 banana
2 cherry
```
# zip関数
複数のリストを組み合わせるzip関数の使い方について説明します。
```py:Python
days = ['Mon','Tue','Wed']
fruits = ['apple','banana','orange']
drinks = ['cofee','tea','juice']

for day, fruit, drink in zip(days, fruits, drinks):
    print(day, fruit, drink)

print('------------------------------------------------')

names = ['Alice', 'Bob', 'Charlie']
scores = [85, 90, 95]

zipped = zip(names, scores)

# zipオブジェクトをリストに変換して表示
print(list(zipped))

print('------------------------------------------------')

names = ['Alice', 'Bob', 'Charlie']
scores = [85, 90, 95]

result = dict(zip(names, scores))
print(result)
```
```:outcome
Mon apple cofee
Tue banana tea
Wed orange juice
------------------------------------------------
[('Alice', 85), ('Bob', 90), ('Charlie', 95)]
------------------------------------------------
{'Alice': 85, 'Bob': 90, 'Charlie': 95}
```
# 関数
関数の定義方法、引数の渡し方、戻り値の扱いについて学びます。
```py:Python
def add(a,b):
    return a + b

print(add(3,5))

print('------------------------------------------------')

def self_introduction(name):
    print(f'My name is {name}.')
    #print('My name is {}.'.format(name))という書き方でも可

self_introduction('Mike')
```
```:outcome
8
------------------------------------------------
My name is Mike.
```
# ジェネレーター
遅延評価を行うジェネレーターの作成と使用について説明します。
```py:Python
def count_up_to(max):
    count = 1
    while count <= max:
        yield count  # 値を返して、次の呼び出しまで状態を保持する
        count += 1

a = count_up_to(3)
print(next(a))
print('この間にほか出力があっても影響なし')
print(next(a))
print(next(a))
```
```:outcome
1
この間にほか出力があっても影響なし
2
3
```
# 内包表記
リスト内包表記や辞書内包表記を使って、効率的にデータを生成する方法を説明します。
```py:Python
#リストの内報表記
create_list = [i for i in range(10)]
print(create_list)
print(type(create_list))
#タプルの内報表記
create_tuple = tuple(i for i in range(10))
print(create_tuple)
print(type(create_tuple))
#辞書の内報表記
create_dict = {i:i*i for i in range(10)}
print(create_dict)
print(type(create_dict))
#集合の内報表記
create_set = {i for i in range(10)}
print(create_set)
print(type(create_set))
#ジェネレータの内報表記
create_gen = (i for i in range(4))
g = create_gen
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(type(create_gen))
```
```:outcome
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<class 'list'>
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
<class 'tuple'>
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
<class 'dict'>
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
<class 'set'>
0
1
2
3
<class 'generator'>
```
# ラムダ
匿名関数であるラムダ式の使い方について説明します。
```py:Python
## lambda 引数: 表現

# 2つの数の合計を返すラムダ関数
add = lambda x, y: x + y
# 使用例
result = add(3, 5)
print(result)

print('------------------------------------------------')
'''
map 関数は、指定した関数を iterable の各要素に適用し、その結果を返します。
結果は map オブジェクトとして返されるため、通常はリストに変換して使用します。
map(function, iterable)
'''
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)

print('------------------------------------------------')
'''
filter 関数は、指定した関数が真（True）を返す要素だけを含む新しい iterable を返します。
これも filter オブジェクトとして返されるため、通常はリストに変換して使用します。
filter(function, iterable)
'''
numbers = [1, 2, 3, 4, 5]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)

print('------------------------------------------------')
'''
sorted 関数は、指定した iterable をソートして、新しいリストを返します。
デフォルトでは昇順にソートされますが、reverse 引数を使用して降順にすることもできます。
sorted(iterable, key=None, reverse=False)
'''
points = [(2, 3), (1, 2), (3, 1)]
# 1つ目の要素でソート
sorted_points = sorted(points, key=lambda point: point[0])
print(sorted_points)  # 出力: [(1, 2), (2, 3), (3, 1)]
```
```:outcome
8
------------------------------------------------
[1, 4, 9, 16, 25]
------------------------------------------------
[2, 4]
------------------------------------------------
[(1, 2), (2, 3), (3, 1)]
```
# クロージャー
関数が定義されたスコープの変数を保持するクロージャーの概念について説明します。
```py:Python
def outer_function(msg):
    def inner_function():
        print(msg)
    return inner_function

# クロージャーを生成
my_greet = outer_function("Hello, World!")
my_greet() 
```
```:outcome
Hello, World!
```
# デコレーター
関数に新しい機能を追加するデコレーターの使い方を学びます。
```py:Python
def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()  # 元の関数を呼び出す
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()
```
```:outcome
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
```

# 例外処理
try-except文を使用して、エラーが発生した場合の処理方法を学びます。
```py:Python
'''
try:
    # 実行したい処理
except ExceptionType:
    # 例外が発生した場合の処理
else:
    # 例外が発生しなかった場合の処理
finally:
    # 常に実行される処理

'''
def divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        print("Error: ゼロでは割れません!")
        return None
    except TypeError:
        print("Error: 型が適切でないです!")
        return None
    else:
        print("成功!")
        return result
    finally:
        print("完了！！！！")

# 正常なケース
print(divide(10, 2)) 
print('------------------------------------------------')

# 例外ケース1: ゼロ除算
print(divide(10, 0))  
print('------------------------------------------------')

# 例外ケース2: タイプエラー
print(divide(10, "a"))  
```
```:outcome
成功!
完了！！！！
5.0
------------------------------------------------
Error: ゼロでは割れません!
完了！！！！
None
------------------------------------------------
Error: 型が適切でないです!
完了！！！！
None
```

# おわりに
ここではpythonの様々な文法などについて記載しました。後半は難しい文法ばかりで僕も正直理解しきれていません。なので、これからは実際にアプリなどを作ることでこれらを理解できるようにしたいです。もし間違いなどを見つけた場合は教えてくれると嬉しいです。