跳至主要内容

17 篇文章 含有標籤「web」

檢視所有標籤

自學程式設計學習資源懶人包

· 閱讀時間約 7 分鐘

隨著資訊科技的發展,目前網路上和坊間有許多的自學電腦科學和程式設計的學習資源,但初學者在面對琳琅滿目的學習資源往往無所適從,因此本文整理了散落各地的自學程式設計學習資源懶人包和學習藍圖提供讀者參考,也歡迎讀者一起補充:)

學習程式設計最重要的是了解電腦科學背後的思考模式和邏輯分析,對於非本科系或是程式設計自學者來說,培養興趣累積成就感是最重要的,建議先從解決生活上著手,透過寫程式解決生活上的問題,等累積了興趣和成就感後重新學習基礎電腦科學知識。以下是初學者學習藍圖建議供讀者參考:

  1. 確認你的學習動機、設定個學習目標
  2. 選擇一門適合你的程式語言入門和工具
  3. 大量閱讀、參與課程、動手實作解決生活上問題,把手弄髒並記錄心得
  4. 組織、參與社群、練習問個好問題
  5. 熟悉函數程式設計、物件導向、框架、設計模式
  6. 重新學習資料結構、演算法、作業系統/系統程式、計算機組織、網路通訊等基礎電腦科學知識(程式解題)
  7. 學習進階電腦科學知識

延伸閱讀:

  1. 非本科生,我想半路出家學寫程式,該如何開始?
  2. Python Web 程式設計入門實戰
  3. JavaScript 程式設計新手村課程
  4. HappyCoder 自學程式設計學院臉書社團

實務程式設計

  1. [中 & 英] Codecademy

    codecademy

    Codecademy 是非常知名的線上學習程式設計的平台(有許多免費的課程),課程設計互動性和趣味性都相當不錯,相當適合初學者練習。課程也運用遊戲化(gamification)徽章和關卡設計也讓學習者更有動力學習。目前除了 HTML/CSS/JavaScript 網頁程式設計外,也有 Python、Ruby、Java 等程式語言可以學習(課程也有持續更新),不過 Codecademy 的內容相對基本,若想要在熟悉語法外更進一步學習實務開發應用程式的話就要額外再找其他學習資源了,但仍不失為一個很好的新手入門方式。

    課程深度:✦ 費用:免費、付費

  2. [英] Code School

    codeschool

    Code School 也是蠻知名的線上程式設計學習平台,與 Codecademy 類似,除了有提供學員線上即時動手實作練習、遊戲化徽章累積的設計外也有影片教學。課程內容也相當豐富貼近實務(JavaScript、Ruby、Git 等)。

    課程深度:✦✦ 費用:免費、付費

  3. [英] Code.org

    code.org

    適合中小學或完全初學的朋友練習,使用圖形化 Scratch 式拖拉程式設計方式。透過簡單的方式體驗程式設計的背後邏輯運作原理。

    課程深度:✦ 費用:免費

  4. [英] W3Schools Online Web Tutorials

    w3schools

    提供豐富的 Web 開發相關學習資源和查詢,適合在實際開發時學習參考查詢使用。

    課程深度:✦ 費用:免費

  5. [中 & 英] Mozilla Developer Network

    MDN

    由 Mozilla 社群維護的技術文件和教學內容,提供 Open Web 相關學習資源(HTML/CSS/JavaScript、Web API、Python)和 API 標準查詢。

    課程深度:✦✦ 費用:免費

  6. [英] FreeCodeCamp

    freecodecamp

    主要提供 HTML/CSS/JavaScript 線上學習資源和討論社群,並提供非營利組織專案實習機會。

    課程深度:✦ 費用:免費

  7. [英] TreeHouse

    teamtreehouse

    TreeHouse 和 Code School 類似,有影片教學也有互動練習,主要提供各種主流程式語言和技術組合的線上課程,包含了行動應用開發、網站開發、遊戲開發等實務課程。

    課程深度:✦✦ 費用:付費

  8. [中 & 英] Udemy

    udemy

    Udemy 是一個全面性的線上課程平台,提供素人講師線上分享技能的機會,課程十分多元貼近實務。除了網站開發、行動應用程式等技術領域外,也有許多非技術領域的課程(例如:行銷管理、創業、攝影、音樂創作等)。

    課程深度:✦✦ 費用:付費

  9. [中 & 英] Udacity

    udacity

    Udacity 與許多知名企業(Google、Facebook)合作提供許多前沿技術的線上教學,例如:人工智慧、深度學習、VR、Web、Mobile 技術等。此外,也提供微專業(Nanodegree)一系列課程和工作機會的媒合。

    課程深度:✦✦✦ 費用:免費、付費

  10. [英] DataCamp

    datacamp

    可以稱作資料科學版本的 Codecademy,使用互動學習方式線上學習資料科學,對於資料科學有興趣的讀者可別錯過了。

    課程深度:✦✦ 費用:免費、付費

基礎電腦科學

  1. [英] Coursera

    coursera

    Coursera 與許多知名大學合作(Stanford、賓州大學、北京大學、台灣大學等),提供教授可以線上授課的平台,學生也可以在家就上到一流學府的課程。與一般課程一樣需要繳交作業,若能完成課程修業規定,可以申請證書。

    課程深度:✦✦✦ 費用:免費、付費

  2. [英] edX

    edx

    edX 與 Coursera 類似與許多知名大學合作(MIT、哈佛大學、UCB等),提供教授可以線上授課的平台。

    課程深度:✦✦✦ 費用:免費、付費

程式解題

  1. [英] LeetCode

    leetcode

    LeetCode 又稱軟體工程師的 GRE(英文檢定),是一個線上解題平台,內含許多演算法和資料結構的題目,是許多準備軟體工程面試的面試者常用的工具。

  2. [英] Hacker Rank

    hackerrank

    Hacker Rank 也是一個線上解題平台,除了解題外也提供教學內容幫助學員學習,適合不想單純解題的使用者。

  3. [英] CodeFights

    codefights

    CodeFights 可以讓你和世界各地的程式設計師對戰,讓寫程式變成像圍棋一樣一場場對奕,十分有趣。

  4. [英] Codewars

    codewars

    Codewars 也是一個程式挑戰的解題平台,提供許多種語言讓使用者可以練習。

  5. [英] Kaggle

    kaggle

    Kaggle 和許多知名企業和單位合作提供資料科學問題,讓參賽者可以解題獲得獎勵和合作機會。

總結

以上整理了散落各地的自學程式設計學習資源懶人包和學習藍圖提供讀者參考,歡迎讀者一起補充,也歡迎加入我們的 臉書學習社群,分享你的自學程式設計心得和經驗。至於初學者若對於程式設計有興趣的話,不妨從 PythonJavaScript 入手,開啟你的程式設計之旅吧:)

參考文件

  1. Google - Guide for Technical Development
  2. Coursera
  3. edX
  4. Udacity
  5. OSS
  6. FreeCodeCamp
  7. Future Learn
  8. Stanford University
  9. MIT Open Courseware
  10. Obtaining a Thorough CS Background Online
  11. JavaScript 程式設計新手村課程
  12. 非本科生,我想半路出家學寫程式,該如何開始?
  13. 卡卡MOOC資源站

Python 101 快速入門教學

· 閱讀時間約 14 分鐘

Python 101 快速入門教學

Python Web 程式設計入門實戰課程準備上課囉!

Python 是一種物件導向、直譯式的跨平台電腦程式語言,它包含了一組功能完備的標準庫和豐富套件生態系,可以輕鬆完成很多常見的任務(例如:讀寫檔案、自然語言處理、網路爬蟲、網站開發、機器學習等),因為它可以很輕易整合其他底層語言,所以又稱為膠水語言。它的語法簡單,與其它大多數程式設計語言使用大括弧不一樣,它使用縮進來定義語句塊。由於具備簡潔易學等特性,許多開發者推薦 Python 為初學者第一個學習的程式語言。由於版本更迭,我們接下來討論的主要是以 Python3 為主,若電腦沒有安裝的話,你可以在官方網站下載,若你不是安裝 Anaconda 這個 all-in-one 版本的話(自帶許多套件和科學運算工具),記得要安裝 pipIPython

Python 設計風格

Python 主要設計的原則和特色就在於簡潔:應該會有一種明顯的作法(最好也只有一種),可以完成工作。

更多有關 Python 設計風格可以在終端機進入 python3 互動模式後輸入 import this

$ python3
Python 3.5.2 (default, Oct 11 2016, 05:00:16)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import this

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

空白格式

首先,我們要了解 Python 和其他語言最大的不同就是使用縮排來切分程式碼,這和其他語言使用 不同。

for i in [1, 2, 3]:
print(i)
for j in [1, 2, 3, 4]:
print(j + i)

print('finish')

不過初學者很容易在縮排遇到問題,若是出現以下訊息就可以檢視是否哪裡縮排有問題:

IndentationError: expected an indented block

模組

在 Python 生態系中有豐富的模組和工具。一般情況預設不會載入任何模組,但當你有特定開發需求可以使用第三方工具將模組匯入(import)。若是當模組名稱很長時通常我們會使用別名。

import re as regex

my_regex = regex.compile('[0-9]+', regex.I)

若是只是需要模組中的特定功能,也可以使用比較精準的引入方式 from import,引入到整個命名空間中,使用時前面就不用寫模組名(但要注意有可能覆寫):

from collections import defaultdict, Counter
lookup = defaultdict(int)
my_counter = Counter()

資料型別

在 Python 有以下幾種內建的資料型別,基本資料型別有 Number、String、Boolean

  1. 數字(Number)

    num1 = 3
    num2 = 2
    num3 = num1 / num2
  2. 字串(String) 字串使用上會使用單引號或雙引號成對包起(', ")

    str = 'data engineer'
    # 字串長度
    len(str)
    # 原始字元
    es_str = r'\t'
    # 2
    len(es_str)

    若是多行的情形:

    multi_line_str = """
    多行
    多行
    """
  3. 布林值(Boolean) 決定邏輯判斷,TrueFalse。注意在 Python 中布林值首字是大寫

    is_num_bigger_than_one = 1 < 2

    在 Python 中 None 地位類似於 null

    x = None
    print(x == None)

    以下為 Python 的 Falsy 值:

  • False

  • None

  • []

  • ""

  • set()

  • 0

  • 0.0

    可以搭配 and, or, not 使用

  1. 列表(List) 列表可以說是 Python 中最基礎的一種資料結構。所謂列表指的就是一群按照順序排序的元素(類似於其他程式語言的 array,但多一些額外功能)。

    list_num = [1, 2, 3]
    list = ['string', 1, [], list_num]
    list_length = len(list_num)
    num_sum = sum(list_num)

    print(list_length)
    print(num_sum)

    運用 [] 取值(index 從 0 開始):

    x = range(10) # [0, 1, 2, ..., 9]
    zero = x[0] # 0
    nine = x[-1] # 9
    x[0] = -1

    切割([起始 index, 結束 index 但不包含]):

    print(x[:3]) # [-1, 1, 2]
    print(x[3:]) # [3, 4, 5,..., 9]
    print(x[1:5]) # [1, 2, 3, 4]
    print(x[0:-1]) # [1, 2, ..., 8]
    print(x[-1:-1]) # [-1, 1, ..., 9]

    檢查元素是否在列表中(逐一檢查,效率較差):

    1 in [1, 2, 3] # True

    串接列表:

    x = [1, 2, 3]
    x.extend([4, 5, 6])
    x = [1, 2, 3]
    y = x + [4, 5, 6]
    x = [1, 2, 3]
    x.append(0) # [1, 2, 3, 0]

    賦值方式:

    x, y = [1, 2]
    _, y = [1, 2]
  2. 元組(Tuple) Tuple 類似於 List 的兄弟,比較大差別在於 Tuple 是 immutable,也就是說宣告後不能修改。列表使用 [],而元組使用 ()

    my_list = [1, 2]
    my_tuple = (1, 2)
    my_list[1] = 3

    try:
    my_tuple[1] = 4
    except TypeError:
    print('cannot modify a tuple')

    多重賦值

    x, y = 1, 2
    x, y = y, x # x == 2, y == 1
  3. 字典(Dictionary)

    字典類似 map,包含鍵值與對應的值,可以快速取出對應值:

    dict1 = {} # 建議寫法
    dirct2 = dict()
    grades = { 'Mark': 70, 'Jack': 40 }

    grades['Mark']

    給定值:

    grades['happycoderorg'] = 100
    len(grades) # 3

    使用事先檢驗鍵或是使用 get 方法:

    try:
    grade = grades['XD']
    except KeyError:
    print('no grade for XD')

    grades.get('XD', 40) # 若無則使用 default 值

    取出所有值:

    grades = { 'Mark': 70, 'Jack': 40 }
    grades.keys() # 所有鍵值組成的 list
    grades.values() # 所有值組成的 list
    grades.items() # 所有鍵值組成的 tuple of list [('Mark', 70)]

    defaultdict

    當你檢查一個不存在的鍵值時,會用零參數函式添加一個事先設定的新值,這是一種比較優雅的作法

    在介紹 defaultdict 之前先介紹一般作法

    # 例外處理
    word_counts = {}
    for word in document:
    try:
    word_counts[word] += 1
    except KeyError:
    word_counts[word] = 1
    # 使用 get
    word_counts = {}
    for word in document:
    previous = word_counts.get(word, 0)
    word_counts[word] = previous_count + 1

    defaultdict 作法(不用每次檢查鍵直視否存在)

    # 匯入 defaultdict
    from collections import defaultdict

    word_counts = defaultdict(int) # 會生成 0
    for word in document:
    word_counts[word] += 1

    也可以使用 list 或 dict 甚至是自己定義的函式來做為 defaultdict 的零參數函式:

    dd_list = defaultdict(list)
    dd_list[1].append(2) # { 1: [2] }

    dd_list = defaultdict(list)
    dd_list['Mark']['City'] = 'Bay Area' # { 'Mark': { 'City': 'Bay Area'} }

    dd_list = defaultdict(lambda: [0, 0])
    dd_pair[2][1] = 1

    Counter:可以把一系列值轉成類似 defaultdict(int) 的東西,裡面每個值都對應到相應的數量,主要會使用來建立直方圖

    from collections import Counter

    c = Counter([0, 1, 2, 0]) # { 0: 2, 1: 1, 2: 1 }
    word_counts = Counter(document)

    每個 Counter 實例都有個 most_common 的方法

    for word, count in word_counts.most_common(10):
    print(word, count)
  4. 集合(Set) 集合類似數學中的集合,裡面包含不重複的元素值

    s = set()
    s.add(1) # { 1 }
    s.add(2) # { 1, 2 }
    s.add(2) # { 1, 2 }
    len(s) # 2
    1 in s # True

    集合在判斷元素是否存在的效率相對較好,此外,對於判斷不重複值也很方便

    list_item = [1, 2, 3, 1, 2, 3]
    set_item = set(list_item) # {1, 2, 3}
    lsit(set_item) # [1, 2, 3]

解析式列表(comprehensive list)

在 Python 我們通常會需要把某個 list 轉換成另外一個 list,比如只挑選其中幾個元素,或是對期中某些元素進行轉換。

even_numbers = [x for x in range(5) if x % 2 == 0]
squares = [x for x in range(5) if x % 2 == 0]
even_squares = [x * x for x even_numbers]

# 不操作值的話
zeros = [0 for _ in even_numbers] # 和 even_numbers 長度一樣值都為 0 的串列

建立 set 和 dict

square_dict = { x : x * x for x in range(5) }
square_set = { x * x for x in [1, -1] } # { 1 }

pairs = [(x, y) for x in range(10) for y in range(10)] # (0, 0), (0, 1)
p = [(x, y) for x in range(3) for y in range( x + 1, 10)]

函式

函式(function)是重複使用的程式區塊,有輸入輸出。在 Python 中我們會使用 def 來定義函式:

def sum(x, y):
return x + y

Python 的函數和 JavaScript 一樣,屬於一級函式(first-class)。我們可以將函數指定給某個變數,然後把它傳給某個函數中,就像是平常把參數傳入函式一樣。

def apply_f(fun):
return fun(3, 2)

def sum(x, y):
return x + y

sum_fun = sum
num = apply_f(sum)
print(num) // 5

匿名函數使用方式(類似 ES6 arrow function 簡化寫法,前面是參數後面是操作):

y = apply_f(lambda x: x + 4)

函式參數預設值:

def my_print(message="default"):
print(message)

my_print("hello python")
my_print()

args 與 kwargs

若我們希望函式可以接受任意參數,我們可以使用 args(由無名稱參數組成的元組) 和 kwargs(由無名稱參數組成的字典):

def magic(*args, **kwargs):
print('unnamed args:', args)
print('keywords args:', kwargs)
magic(1, 2, key='word', key2='word2')

# unnamed args: (1, 2)
# keywords args: {'key': 'word', 'key2': 'word2'}

可以用來協助建立以函式當做參數的高階函式:

def double(f):
def g(*args, **kwargs):
return 2 * f(*args, **kwargs)
return g

def f2(x, y):
return x + y

g = doubler_correct(f2)
print(g(1, 2))

常見內建函式

除了自己可以建立函式外,Python 本身也提供許多好用的內建函式:

  • all:列表中所有元素為真

    all([True, 1, { 3 }]) # True
    all([True, 1, { }]) # False
    all([]) # True,沒有元素為假
  • any:列表中只要有任何元素為真

    any([True, 1, {}]) # True
    any([]) # False,沒有元素為真
  • enumerate:列舉

    我們常需要反覆取得列表中每個元素及其索引值

    # choice 1
    for i in range(len(documents)):
    document = documents[i]
    do_something(i, document)

    # choice 2
    i = 0
    for document in documents:
    do_something(i, document)
    i += 1

    使用 enumerate:

    for i, document in enumerate(documents):
    do_something(i, document)

    # 僅需要 index
    for i, _ in enumerate(documents): do_something(i)
  • zip:合併將多個 list 合併成 tuple of list

    list1 = ['a', 'b', 'c']
    list2 = [1, 2, 3]
    zip(list1, list2) # [('a', 1), ('b', 2)]

    zip(*[('a', 1), ('b', 2), ('c', 3)]) == zip(('a', 1), ('b', 2), ('c', 3)) # [('a', 'b', 'c'), ('1', '2', '3')]
    # * 可以參數拆分
    def add(a, b): return a + b
    add(1, 3) # 4
    add([1, 3]) # TypeError
    add(*[1, 3]) # 4
  • range:取得一序列

    range(0, 10) # 0, 1, 2, ... 9
  • random:生成隨機數字

    import random

    randoms = [random.random() for _ in range(4)] # 生成長度為 4 內涵值為 0 - 1 不含 0 的 list

    事實上,random 產生的是偽隨機數字,透過 seed 設定可以取得同樣值

    import random
    random.seed(10) # 把 seed 設為 10
    print(random.random()) # 0.5714025946899135
    random.seed(10) # 把 seed 設為 10
    print(random.random()) # 0.5714025946899135

    隨機產生範圍內數字:

    random.randrange(10)
    random.randrange(3, 6)

    針對列表隨機排列:

    num = range(10)
    random.shuffle(num)
    random.choice(['Mark', 'Bob', 'Jack'])

    隨機取樣不放回:

    nums = range(10)
    random.sample(nums, 3)

    隨機取樣放回:

    nums = range(10)
    random.choice(nums, 3)
  • sort:針對 list 進行排序(由小到大),會改變原來的 list。sorted 不會改變原來 list

    x = [4, 1, 2, 3]
    y = sorted(x) # [1, 2, 3, 4] 不會改變到 x
    x.sort() # x 變成 [1, 2, 3, 4]

    若想改成由大到小排序

    x = sorted([-4, 1, -2, 3, key=abs, reverse=True]) # [-4, 3, -3, 2] 絕對值由大到小

    若是在 key 指定一個函數,就會用這個函數結果去做排序

    wc = sorted(word_counts.items(), key=lambda (word, count): count, reverse=True) # 針對單字數量多到小排序
  • partial:使用函式工具創建另一個函式

    from functools import partial
    def exp(base, power):
    return base ** power
    two_to_the = partial(exp, 2)
    print_two_the(3)
  • map:

    def multiply(x, y):
    return x * y
    map(multiply, [1, 2], [1, 2]) # [1, 4]
  • filter:

    def is_even(x):
    return x % 2 == 0
    filter(is_even, [2, 5, 6]) # [2, 6]
  • reduce:

    def multiply(x, y):
    return x * y
    reduce(multiply, [1, 2, 3]) # 1 * 2 * 3

控制流程

  1. if...elif...else

    if 1 > 2:
    message = 'if onlt 1 were greater than two'
    elif 1 > 3:
    message = 'elif == else if'
    else:
    message = 'else'

    三元運算子:

    parity = 'even' if x % 2 == 0 else 'odd'
  2. for...in

    較複雜情況我們會搭配 continue 和 break 使用:

    for x in range(10): # 0...9 不含 10
    if x == 3:
    continue
    if x == 5:
    break
    print(x)
  3. while

    x = 0
    while x < 10:
    print('x is less than 10')
    x += 1

生成器(generator)與迭代操作

事實上,list 有個問題就是很容易變得很大。例如:range(1000000) 就會製造出一個包含一百萬的元素的 list。若是想要使用其中幾個元素,效能就會變得很差。此時使用生成器(generator)就是一個每次只生成所需數值的一種 lazy 作法。

使用函式和 yield

def lazy_range(n):
i = 0
while i < n:
yield i
i += i
for i in lazy_range(10):
do_something(i)

或是在小括號使用運算解析式

lazy_evens_below_20 = (i for i in lazy_range(20) if i % 2 == 0)

另外,每個 dict 都有一個叫做 items() 的方法

iteritems() # 可以一次生成一個鍵值對

裝飾器(decorator)

裝飾器本身是一個函式,主要是借助閉包力量產生一個可以修飾函式的函式:

@print_fun(title='title:')
def add(*tup):
return sum(tup)

# 以下兩者相同
add(1, 2, 3, 4)
add = print_fun(title='title:')(add)

# 裝飾器撰寫
def print_fun(title):
def decorator(func):
def modified_func(*args, **kwargs):
result = func(*args, ** kwargs)
print(title, result)
return modified_func
return decorator

正規表達式

與許多程式語言一樣,Python 同樣提供正規表達式的用法,可以方便擷取文字。

import re

print.all([
re.match('a', 'cat'),
re.search('a', 'cat')])

物件導向程式設計(OOP)

Python 也是物件導向程式語言:

class Set:
def __init__(self, values=None):
# 建構函數
s1 = Set()
s2 = Set([1, 2, 3])
self.dict = {}
if values is not None:
for value in values:
self.add(value)
def __repr__(self):
return "Set" + str(self.dict.keys())
def add(self, value):
self.dict[value] = True
def contains(self, value):
return value in self.dict
def remove(self, value):
del self.dict[value]
# 使用物件
s = Set([1, 2, 3])

s.add(4)

print(s.contains(4))

例外狀況

若是程式出現錯誤的話會送出 exception,若不妥善處理的話程式很有可能會掛掉,在 Python 中例外處理可以使用 try...except:

try:
print(1/0)
except ZeroDivisionError:
print('cannot divide by zero')

總結

本文快速介紹了 Python 的基礎概念,當讀者學會了 Python 後,事實上可以嘗試使用 Python 開發不同的網路應用程式或是資料科學,甚至是自然語言處理的應用。更多 Python 教學內容都在 Python Web 程式設計!

延伸閱讀

  1. 15 Essential Python Interview Questions
  2. 8 Essential Python Interview Questions*
  3. Python Interview Questions
  4. What are good Python interview questions?
  5. Top 40 Python Interview Questions & Answers
  6. Top Python Interview Questions And Answers
  7. Python Interview Questions
  8. 12步教你理解Python装饰器

(image via fedoramagazine