---
slideOptions:
spotlight:
enabled: false
---
# Coding Convention
> [time=Thu, Nov 4]
> [name=Brian Chou] [name=yaya] [name=nick] [name=andy] [color=#e56e2d]
---
## Python 自動格式化工具
- linter:在程式未執行情況下檢查**程式語法正確性**的工具 ex: pylint
- formatter:自動修正排版問題的工具 ex: yapf
----
## pylint


----
## Global variables
- Avoid Global variables
```python=
_MAX_HOLY_HANDGRENADE_COUNT = 3
```
---
## Comprehensions
- 複雜的表達式可能難以閱讀
----
### no
```python=
result = [complicated_transform(
x, some_argument=x+1)
for x in iterable if predicate(x)]
```
### yes
```python=
result = [complicated_transform(x)
for x in iterable if predicate(x)]
```
----
### no
```python=!
result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]
```
### yes
```python=
result = []
for x in range(10):
for y in range(5):
if x * y > 10:
result.append((x, y))
```
---
## lambda
- 函數功能很小,可以使用 lambda來快速完成 function
- 條件表達簡單時可用,__複雜則盡量避免__
```python=
add = lambda a, b: a+b
a = 10
b = 20
c = add(a, b)
print(c)
```
---
## Default Argument
- function’s parameter要有 Default Argument
- Default Argument 只會被決定一次,必須特別注意傳入的參數是否為 mutable<!-- 因為 Python沒有 overloading: 當定義了多個同名函數時,後面的函數會覆蓋前面的函數 -->
- 不要使用可變對像作為默認值
----
### Example
```python=
No: def foo(a, b=time.time()):
...
Yes: def foo(a, b=None):
if b is None:
b = []
```
---
## True/False Evaluations
- 盡量使用隱含False意思(在Python中會被判定為False)的值,像是`0, None, [], {}, ''`
- 處理整數時,直接與0比較可以避免一些問題
----
```python=
if not users:
print('no users')
if i % 10 == 0:
self.handle_multiple_of_ten()
def f(x=None):
if x is None:
x = []
```
---
## Lexical Scoping
- Lexical Scoping 代表著區塊間的包裹關係,被包裹在內層的區塊可以保護自己的變數不被外層取用,相反的外層區塊的變數還是可以被內層區塊使用
- Python中的這個特性可以使用
- 但只能讀取外層的變數,不能賦值。賦值會讓對外層變數的參考變成對區域變數的參考
----
```python=
i = 4
def foo(x: Iterable[int]):
def bar():
print(i, end='')
# ...
# A bunch of code here
# ...
for i in x: # Ah, i *is* local to foo, so this is what bar sees
print(i, end='')
bar()
```
So `foo([1, 2, 3])` will print `1 2 3 3`, not `1 2 3 4`.
---
## Function and Method Decorators
- 只在有明顯優點時使用Decorator
- 避免staticmethod(使用模組級別的Function替代),只在一些情況使用classmethod
---
## Threading
- 不要依賴Python內建的原子操作
- 線程間溝通使用queue或lock
---
## Power Features
- 不要使用Python裡一些太花俏的功能
---
## Type Annotated Code
- 建議加上Type Hint
- 可以使用其他檢查工具如pytype
---
## Python Style Rules
---
## Semicolons ;
## Line length characters
----
- Maximum 80
```python=
# 括號
foo_bar(self, width, height, color='black', design=None, x='foo',
emphasis=None, highlight=0)
# 文字字串不符合單行
x = ('This will build a very long long '
'long long long long long long string')
#with
with very_long_first_expression_function() as spam:
with very_long_second_expression_function() as beans:
place_order(beans, spam)
```
---
## Parentheses()
tuples
- return statements
- conditional statements
---
## Indentation
用空格取代tab
```python=
#spaces
foo = long_function_name(var_one, var_two,
var_three, var_four)
# 6 tabs
foo = long_function_name(var_one, var_two,
var_three, var_four)
```
### commas
```python=
golomb4 = [
0,
1,
4,
6,
]
```
----
### Blank Lines
Two blank lines between top-level definitions, be they function or class definitions.
----
### Whitespace
```python=
# spaces
# yes
spam(ham[1], {'eggs': 2}, [])
# no
spam( ham[ 1 ], { 'eggs' : 2 }, [ ] )
#binary operators
# yes
x == 1
# no
x==1
# comments
#yes
foo = 1000 # comment
long_name = 2 # comment that should not be aligned
#no
foo = 1000 # comment
long_name = 2 # comment that should not be aligned
```
---
### Comments
> **我們決定用中文:D**
- Args
- Returns(or Yields: for generators)
- Raises
```python=
def fetch_smalltable_rows(table_handle: smalltable.Table,
keys: Sequence[Union[bytes, str]],
require_all_keys: bool = False,
) -> Mapping[bytes, tuple[str, ...]]:
```
---

----
- class
-- public

---
### Strings
- f-string, the % operator, or the format
```python=
x = f'name: {name}; score: {n}'
```
- Avoid using the + and += operators
```python=
x = 'name: ' + name + '; score: ' + str(n)
```
- 引用
```python=
Python('Why are you hiding your eyes?')
Gollum("I'm scared of lint errors.")
```
----
### Error Messages
```python=
if not 0 <= p <= 1:
raise ValueError(f'Not a probability: {p!r}')
try:
os.rmdir(workdir)
except OSError as error: # Interpolated pieces
logging.warning('Could not remove directory (reason: %r): %r',error, workdir)
```
---
### TODO
- bug reference
- yourusername
[name=yaya] [name=brian] [name=nick] [name=andy]
```python=!
# TODO(crbug.com/192795): Investigate cpufreq optimizations.
# TODO(yourusername): File an issue and use a '*' for repetition.
```
---
## import
- 不要將 `import` 寫在同一行
- 依照字典序排序 import
```python=
import sys
import tensorflow as tf
from otherproject.ai import mind
```
---
## Statement
- only one statement per line
- 除非只有單行`if`敘述,且沒有`elif`
---
## Getters and Setters
- 除非讀取/寫入變數時需要複雜的操作,否則簡單的讀寫變數應避免用Getters/Setters,而是直接將變數設為 public
---
## Naming
- 命名應使用描述性的文字
- 禁止縮寫
- package/module name 禁止包含 `-`
- 避免不必要的描述 i.e. `id_to_name_dict`
- `CapWords` for class names.
- `lower_with_under.py` for module names.
----

---
## Function
- 函數長度不應超過40行
- 如果超過則儘可能切割成更多更小的功能
---
## 縮排
```python=
def my_method(
self,
other_arg: Optional[MyLongType],
) -> tuple[MyLongType1, MyLongType1]:
```
- 函數參數過長時,一行一參數
- 為了讓最後的return可以換行,在最後一個參數加上逗號是可以的
----
```python=
def my_function(
long_variable_name:
long_module_name.LongTypeName,
) -> None:
```
- 函數參數一行還是放不下時,切斷的地方應再向內縮排
---
## 循環引用(Circular Dependencies)
定義:兩個檔案互相 import 對方
- 雖然可用一些方法繞過錯誤,但盡量避免
---
## Typing
如果區域變數的型別難以辨識,可以加上 variable annotations
----
### example:
```python=
a: Foo = SomeUndecoratedFunction()
```
:::warning
冒號右邊要空白,左邊不需要
:::
----
:::warning
舊的語法,勿用
```python=
a = SomeUndecoratedFunction() # type: Foo
```
:::
---
### TypeVars
是個好東西,可以的話多多使用
```python=
from typing import TypeVar
_T = TypeVar("_T")
...
def next(l: list[_T]) -> _T:
return l.pop()
```
```python=
AddableType = TypeVar("AddableType", int, float, str)
def add(a: AddableType, b: AddableType) -> AddableType:
return a + b
```
---
## 臨別贈言(?
- 始終保持一致 **BE CONSISTENT.**
- 在開始 coding 之前先看看他周圍的 codes,永遠和周圍使用一樣的風格
---
# Roles & Responsibilities
----
## 工作:
- 討論、評估規格、改進
- 討論實作方式
- 寫程式,嘗試解決各種技術困難、與時俱進
- 錯誤追蹤和回報
- 撰寫註解
- 設計系統架構
- 與前端協作
- 不停學習
----
## 能力:
- 基本的伺服器指令、網路知識、資料庫操作 / SQL、API 串接
- 暸解 security, authentication等議題
- 耐心與堅持
- 邏輯思考
----
## 價值與挑戰:
- 確保資料正確性
- 系統穩定性
- 程式的彈性
---
# end~~
{"metaMigratedAt":"2023-06-17T13:27:13.193Z","metaMigratedFrom":"YAML","title":"Coding Convention","breaks":true,"contributors":"[{\"id\":\"c6f70f44-39e6-4fbc-b317-5e503cc1858e\",\"add\":9,\"del\":0},{\"id\":\"dacf2091-9992-4f5d-a557-c499f1dd5d55\",\"add\":3958,\"del\":1049},{\"id\":\"dbd3c3f6-7099-483f-b85b-2d0c22ec4ddb\",\"add\":2775,\"del\":779},{\"id\":\"ab1b9a7e-f184-4486-a8d4-a4431acd03d2\",\"add\":1746,\"del\":748},{\"id\":\"ff25936e-3d12-40ca-9fd0-f1fc893ea090\",\"add\":1079,\"del\":56}]"}