Blog Cover Image

Inspire you to have New thinking, Walk out your unique Road.

後端小菜鳥學習記錄(9)- 將三觀導正

Posted on Oct 22, 2018

在歷經了新手腦袋炸開混沌時期,我們逐漸向更高階層的程式 level 邁進

上段時期,取得門票進入了軟體開發的殿堂

一個一個在學校活蹦亂跳,觀念不正確,基礎無功力,隨意運用估狗查詢到的方法亂拼亂湊,免強拚出一個一個可以動,卻醜陋的玩具們

剛踏入殿堂中,眼前滿滿荊棘及被濃霧包圍看不到盡頭向上蔓延的層層階梯

新鮮人也好,程式新人也好,兩者加起來的身份讓自己既無攻擊力也毫無防備力

剛開始在路途上的階段,天天頭暈炸開,腦袋不靈光是正常,分不清哪個是實哪個是虛

這條道路上,除了可看見的荊棘陷阱外,更多是來自內心的敵人,害怕,焦慮,沒自信

隨著一次一次的滑落,跌倒,重新來,慢慢抓到訣竅,路途也就順了

只是,有多少人能夠在這段時期存活下來呢

才週一一早就很有感覺,可惜是上班時間

昨天晚上嘗試清理了自己的頂輪,嘗試了我的第一次脈輪清理,結果現在頭暈 QQ

但昨天已經沒有前幾週這麼大的上班壓力,就是那種想到明天是上班日,就覺得壓力很大,很害怕做錯很多事

才從上班幾天開始,內心,整個身體都在一個混鈍混亂的階段(喔不,是今年開始都這樣),所以確定有工作後,除了工作上學習,在這以往緊湊的生活步調,全部在進入工作後整體慢了下來。

這短短一個月,我決定要好好趁這個時候重新整理我的人生

以下,是我上週開始覺得自己終於更上一層樓的一週學習紀錄

10/15

10:30-12:30(2hours)

14:00-19:00(5hours)

10/16

10:30-12:30(2hours)

14:00-19:00(5hours)

#將此欄位每筆資料作加總
Total = df['Number'].sum()

#讀取 df 時,條件限制

df[(df.name == 'Amy') & (df.email == 'Amy@123')][['gender','job']]

***大神開課啦***

當前端與後端互相溝通時,最重要的傳遞是

資料格式要正確

第二,自我重複的現象要避免(修改)

對於工程師來說,變免重複的程式碼,才會進步

若程式碼有重複兩次以上,那麼就須使用別的方法來解決

例如:包成函式使用,總之盡量用更好的方式來解決重複的程式碼!!

#取末三筆資料
df2.iloc[-3:]

10/17

10:30-12:30(2hours)

14:00-19:00(5hours)

Pandas.DataFrame 算平均
df["weight"].mean()

https://stackoverflow.com/questions/31037298/pandas-get-column-average-mean

#轉換成list
index = df_loc.index.tolist()










# Series讀出來的日期欄位都會有Timestamp問題

# 找到了三個解決方法
# 後來是用第一個方法解除
# 1
df.loc[i]['Date'].strftime("%Y-%m-%d")
# 2
Series.dt.date
# 3<code class="descname">
</code>pd<span class="crayon-sy">.</span><span class="crayon-e">to_datetime</span><span class="crayon-sy">(</span><span class="crayon-v">df</span><span class="crayon-sy">[</span><span class="crayon-s">'timestamp'</span><span class="crayon-sy">]</span><span class="crayon-sy">,</span> <span class="crayon-v">unit</span><span class="crayon-o">=</span><span class="crayon-s">'s'</span><span class="crayon-sy">)</span>



















#浮點數只要後兩位







float("{0:.2f}".format(13.949999999999999))

#這是我的作法
average = float("{0:.2f}".format(df['Number'].mean()))

https://stackoverflow.com/questions/455612/limiting-floats-to-two-decimal-points

至於 df 的 timedelta 的 Time 型別 無法轉換成正常時間輸出會報錯

這個部分我直接硬做用 str()包起來做了 QQ,目前還沒找到解法


10/18

14:00-19:20

https://docs.python.org/3/library/random.html

# 學習Random
random.randint(1,4)

word_list = ["A", "R", "W", "I", "M", "O", "C"]
random.choice(word_list)

end_qty = 40 + random.randint(0, 100)

https://www.cnblogs.com/xuchunlin/p/6305720.html

<strong>#百分比转换位小数</strong>




s = '20%'  # 默认要转换的百分比是字符串
aa = float(s.strip('%')) # 去掉s 字符串中的 %
bb = aa/100.0  #运行环境是Python2.7   其中Python2.X  与 python 3X中的除法是有區别
print bb
# 输出结果是 0.2

# 小数转换位百分比

#方法一

a = 0.3214323
bb = "%.2f%%" % (a * 100)
print bb
# 输出结果是32.14%

#方法二

a = 0.3214323

b = str(a*100) + '%'
print b
# 输出结果是32.14323%


# 如果想保留小数点后两位
c = str(a)[:4]+ '%'
print c
# 输出结果是0.32%

***大神開課啦***

  1. 寫一個後台的函式有他的幾個步驟,要依照步驟去做處理

  2. 要預期這個函式可能會出什麼錯,然後在函式裡先做處理

  3. 用 sql 函式取資料包成 Pandas 做處理

    寫一個後台的函式有他的幾個步驟,要依照步驟去做處理

通常一個後台的函式會有三個步驟

  1. 從資料庫取得資料

  2. 對資料做處理

  3. 將資料 Return 回前端

在第一個步驟可以先去判斷資料是有沒取到

  1. 沒取到 >> 回傳空值

  2. 有取到 >> 回傳資料

可以在這個步驟先判斷有沒有取到資料

再來第二個步驟:對資料做處理

在這個步驟會對資料做處理,所謂的例外案例函式

Try:
Except:

絕大部分會用在這,這個部分也會出比較多錯也就是說

要預期這個函式可能會出什麼錯,然後在函式裡先做處理

這個步驟要先把自己預期可能會發生的錯誤處理一次

真的不確定的才會包成 Try/Except

第三步驟:將資料 Return 回前端

這個步驟是導致我寫這些的原因哈哈 XD

因為我包成 Try/Except

可是取值是空值(系統卻還是把它當成值來計算),導致我回傳給前端報錯

第三步驟重點是,回傳的型別要是正確的,不然傳給前端會噴錯誤

最後是第三大項

用sql函式取資料包成Pandas做處理

我的做法是將 sql 語法轉換成 Pandas DataFrame 包成一個涵式

然後將這個函式 Import 到其他.py 檔使用

可是歷久了,發現不能確定取的資料是第幾筆,還有很多取的資料需要做排序還是什麼的

造成我寫的.py 檔都要大改 QQ

因為我用的 SQL 函式歷久未修

所以如果將 SQL 語法包成函式,利用 Pandas 使用的話!!!

記得要回去多包幾個不同的 sql 函式唷

我要來大改了 Q0Q

***寫 Git Commit 的要點***

https://blog.louie.lu/2017/03/21/%E5%A6%82%E4%BD%95%E5%AF%AB%E4%B8%80%E5%80%8B-git-commit-message/


10/19

各位朋友早安

早上就先來殘害各位程式學子的雙眼

有鑒於昨日我發現我這幾週努力寫的程式碼要大改後

我就想來寫一下

上面有發了昨天大神指導的地方

這邊我想把我慘不忍睹的程式碼 po 給大家欣賞,順便 po 一下大神的程式碼

***後端程式學子們看過來***

後端工作目前接觸到現在,有一部分是

  • 將資料從資料庫裡撈出來塞給前端

這個流程資料是這樣跑的

資料庫 >> 程式檔內做處理( 一隻一隻函式) >> 塞到函式的Return >> 組成一串Json(json比較常見)

Json >>>>>>>>> 前端收取Json >> 前端做處理

資料庫跟前端是不能變的(至少我一個後端工程師,我能做的就是中間變化的程式碼撰寫)

所以站在程式處理的角度來看

從資料庫 >>>>> 前端

中間的過程分成三個部分

  1. 從資料庫取得資料

  2. 對資料做處理

  3. 將資料 Return 回前端

針對第一部分,目前我的智障做法是

將 sql 函式寫死並轉換成 Pandas 的 DataFrame,再用 DataFrame 做處理

處理完硬轉成 int/float/str,硬塞成 list 給 return 給前端

然後就噴錯炸掉了 QQ

這樣的做法有很大的問題

  • 效能問題

我被罵效能問題,後端我從開始工作到現在遇到的最不可思議(在學校沒遇到)的問題就是效能

因為會接觸到硬體,所以拿取資料,都被大神念說,為什麼我拿了 100 筆資料卻只用一筆資料,不覺得很浪費效能嗎,不只讓處理速度變慢,連帶傳輸也變慢呢!

  • 中間處理很麻煩

還是後端新手的自己卡了幾個大問題,但我都不覺得是問題就拖著,結果我發現....

恩,是個大問題..

因為我的 sql 函式都寫死,自然就沒有彈性,永遠都是取全部的資料或只取到前幾筆資料,所以在第一步驟我就不知道我取的資料不是正確了

取出來又是 DataFrame 值,之後塞到 Return 還要轉成 int/..這樣的型態,才不會報錯!


後來看了大神的程式碼,跟昨天大神們的觀念導正後..

我的思想跟做法有了不一樣的昇華!

大神的做法是

  1. 將 Sql 語法做成活的

  2. 拿取只拿取他想要的那欄

  3. 拿取的時候直接轉成 List/ Dict 這種 Python 的資料形式

這樣不止可以解決不知道拿的資料是不是對的

還能解決之後處理上的大問題

以下就是我跟大神的程式碼 QQ

from flask_sqlalchemy import SQLAlchemy
# init db in app.py
from app import db
import pandas as pd

# 這是我主管寫給我的範例,我就一封不動的抄過來用了
def retrieve_data(table, limit=100):
df = pd.read_sql(
"select * from {} limit {}".format(table, limit), db.engine)

return df

# 抄好抄滿
def retrieve_data_desc(table, desc, limit=100):
df = pd.read_sql(
"select * from {} order by {} DESC limit {}".format(table, desc, limit), db.engine)

return df


""" 大神的程式碼 """

# 讀取時為DataFrame轉成Dict
def query_one_row_as_map(sql, params={}):
df = data(sql, params)
d = {}
for key, value in df.iloc[0].to_dict().items():
d[key] = value
return d

# 讀取時為DataFrame轉成List
def query_one_row_as_list(sql, params={}, key_name='key'):
df = data(sql, params)
d = []
for key, value in df.iloc[0].to_dict().items():
# d.append(dict(key=key, value=value))
d.append({key_name: key, 'value': value})
return d

#讀取時為DataFrame
def data(sql, params={}):
df = pd.read_sql(sql, params=params, con=db.engine)
return df

""" 不過我發現大神的程式碼遇到空資料會報錯,所以利用下列判斷空直方法先在函式裡判斷一次 """







# SQL 語法 Order + Limit
select Date, Number from Info ORDER BY Date DESC LIMIT 10;



















# 利用empty函式檢查有沒有抓到資料
df.empty

https://pandas.pydata.org/pandas-docs/version/0.18/generated/pandas.DataFrame.empty.html

判定dict是否為空值













>>> dct = {}
>>> bool(dct)
False
>>> not dct
True
>>>

https://stackoverflow.com/questions/23177439/python-checking-if-a-dictionary-is-empty-doesnt-seem-to-work


本週分享: 一段 Airflow 與資料工程的故事:談如何用 Python 追漫畫連載

https://leemeng.tw/a-story-about-airflow-and-data-engineering-using-how-to-use-python-to-catch-up-with-latest-comics-as-an-example.html

前端大神導正菜鳥三觀系列:

https://zhuanlan.zhihu.com/p/27172276