這是軟體工程師訪談系列的第三篇文章。我帶來了幾年前做過的挑戰,並且實際上得到了這個職位 - 涉及其他技術面試,例如過去的經驗篩選。
如果您錯過了本系列之前的帖子,可以在這裡找到它們。
這個挑戰也是一項帶回家的編碼任務,我必須開發一個 CLI 程式來查詢 OEIS(整數序列線上百科全書)並返回結果總數以及第一個結果的名稱查詢返回五個序列。
值得慶幸的是,OEIS 查詢系統包含 JSON 輸出格式,因此您可以透過呼叫 url 並將序列作為查詢字串傳遞來取得結果。
輸入與輸出範例:
oeis 1 1 2 3 5 7
Found 1096 results. Showing first five: 1. The prime numbers. 2. a(n) is the number of partitions of n (the partition numbers). 3. Prime numbers at the beginning of the 20th century (today 1 is no longer regarded as a prime). 4. Palindromic primes: prime numbers whose decimal expansion is a palindrome. 5. a(n) = floor(3^n / 2^n).
注意:此結果已過時!
解決這項挑戰的計畫如下:
由於這是一個編碼挑戰,我將使用 Poetry 來幫助我創建專案的結構,並方便任何人運行它。您可以在他們的網站上查看如何安裝和使用 Poetry。
我將首先使用以下內容建立套件:
poetry new oeis
這將建立一個名為 oeis 的資料夾,其中包含 Poetry 的設定檔、一個測試資料夾和一個也稱為 oeis 的資料夾,該資料夾將成為我們專案的根目錄。
我還將添加一個名為 Click 的可選包,它有助於建立 CLI 工具。這不是必需的,可以用 Python 中的其他本機工具替換,儘管不太優雅。
在專案資料夾中,執行:
poetry add click
這會將 click 加入為我們專案的依賴項。
現在我們可以移動到入口點檔案。如果你打開資料夾 oeis/oeis,你會看到已經有一個 __init__.py 檔案。讓我們更新它以導入 Click,以及使用以下命令調用的主函數:
# oeis/oeis/__init__.py import click @click.command() def oeis(): pass if __name__ == "__main__": oeis()
這是我們 CLI 的起點。看到@click.command了嗎?這是來自 click 的包裝器,它將幫助我們將 oeis 定義為命令。
現在,還記得我們需要接收以空格分隔的數字序列嗎?我們需要將其新增為參數。 Click 有一個選項:
oeis 1 1 2 3 5 7
這將新增一個名為序列的參數,並且 nargs=-1 選項告訴點擊它將用空格分隔。我添加了一個列印,以便我們可以測試參數是否正確傳遞。
為了告訴 Poetry 我們有一個命令,我們需要打開 pyproject.toml 並添加以下行:
Found 1096 results. Showing first five: 1. The prime numbers. 2. a(n) is the number of partitions of n (the partition numbers). 3. Prime numbers at the beginning of the 20th century (today 1 is no longer regarded as a prime). 4. Palindromic primes: prime numbers whose decimal expansion is a palindrome. 5. a(n) = floor(3^n / 2^n).
這是新增一個名為 oeis 的腳本,該腳本呼叫 oeis 模組上的 oeis 函數。現在,我們運行:
poetry new oeis
這將讓我們呼叫腳本。讓我們來試試:
poetry add click
完美,我們已經按照我們的預期解析了命令和參數!讓我們繼續討論客戶端。在oeis/oeis資料夾下,建立一個名為clients的資料夾、一個名為__init__.py的檔案和一個名為oeis_client.py的檔案。
如果我們期望在這個專案中擁有其他客戶端,我們可以開發一個基本客戶端類,但由於我們只有這一個,所以這可能被認為是過度設計。在 OEIS 用戶端類別中,我們應該有一個基本 URL,這是沒有路徑的 URL,我們將使用它來查詢它:
# oeis/oeis/__init__.py import click @click.command() def oeis(): pass if __name__ == "__main__": oeis()
如您所見,我們正在匯入 requests 套件。我們需要將它加入 Poetry 才能使用它:
# oeis/oeis/__init__.py import click @click.command() @click.argument("sequence", nargs=-1) def oeis(sequence: tuple[str]): print(sequence) if __name__ == "__main__": oeis()
現在,客戶端有一個不會改變的基本 URL。讓我們深入研究其他方法:
我們還需要更新我們的主文件,以呼叫此方法:
# oeis/pyproject.toml [tool.poetry.scripts] oeis = "oeis:oeis"
這裡我們現在在方法外部建立一個客戶端實例,因此它不會在每次呼叫命令時都建立一個實例,而是在命令內部呼叫它。
執行此命令會產生非常非常長的回應,因為 OEIS 有數千個條目。由於我們只需要知道總大小和前五個條目,因此我們可以執行以下操作:
poetry install
運行這個已經比以前好多了。我們現在列印總大小以及前五個(如果存在)條目。
但我們也不需要所有這些。讓我們建立一個格式化程式來正確格式化我們的輸出。建立一個名為 formatters 的資料夾,其中包含 __init__.py 檔案和 oeis_formatter.py 檔案。
oeis 1 1 2 3 5 7
該文件基本上將前五個結果格式化為我們想要的輸出。讓我們在主文件中使用它:
Found 1096 results. Showing first five: 1. The prime numbers. 2. a(n) is the number of partitions of n (the partition numbers). 3. Prime numbers at the beginning of the 20th century (today 1 is no longer regarded as a prime). 4. Palindromic primes: prime numbers whose decimal expansion is a palindrome. 5. a(n) = floor(3^n / 2^n).
如果您執行此程式碼,您現在將得到:
poetry new oeis
它現在以我們期望的格式返回,但請注意它說找到了 10 個結果。這是錯誤的,如果您在 OEIS 網站上搜索,您會看到更多結果。不幸的是,OEIS API 進行了更新,結果不再傳回包含結果數量的計數。不過,該計數仍然顯示在文字格式的輸出中。我們可以用它來知道有多少個結果。
為此,我們可以更改 URL 以使用 fmt=text 和正規表示式來尋找我們想要的值。讓我們更新客戶端程式碼以獲取文字數據,並更新格式化程式以使用此數據,以便我們可以輸出它。
poetry add click
如您所見,我們新增了兩種新方法:
# oeis/oeis/__init__.py import click @click.command() def oeis(): pass if __name__ == "__main__": oeis()
在這個檔案中,我們只為方法增加了一個新的參數,並用它取代了查詢結果的長度。
# oeis/oeis/__init__.py import click @click.command() @click.argument("sequence", nargs=-1) def oeis(sequence: tuple[str]): print(sequence) if __name__ == "__main__": oeis()
這裡我們只是在客戶端呼叫新方法,並將資訊傳遞給格式化程式。再次運行它會產生我們期望的輸出:
# oeis/pyproject.toml [tool.poetry.scripts] oeis = "oeis:oeis"
程式碼已經基本準備好了。但對於真正的挑戰,請記住盡可能使用 Git,進行小型提交,當然,添加單元測試、程式碼格式化庫、類型檢查器以及您認為需要的任何其他內容。
祝你好運!
以上是軟體工程師訪談 - #EIS CLI的詳細內容。更多資訊請關注PHP中文網其他相關文章!