Golang Saga:编码员在那里又回来了。第1部分:离开郡
#教程 #api #go #data

学习golang的想法已经在我的脑海中流传了一段时间。但是,像我们许多人一样,我经常找到借口将其推迟。不过,就在前几天,我正在阅读this引人入胜的文章,该文章谈论了有效学习的关键在于实际应用我们通过附带项目学习并在此过程中做出个人承诺的内容。

有这句话立即引起了我的注意,这感觉就像是一个信号:使您的目标和进步公开可以帮助您保持正轨并鼓励其他人这样做。当我很清楚时,我意识到我需要一个GO语言的附带项目,在开发过程中我可以与他人公开分享我的进步。

欢迎进入全新冒险的开始!我将撰写一系列技术文章,详细介绍我使用GO从头开始创建附带项目的旅程。这几乎就像观看真人秀一样,您可以在那里逐步见证该项目。就像比尔博一样,我不知道未来会发生什么,但是我对前景感到兴奋。

但是我不会一个人这样做。没有一个伟大的冒险是单枪匹马完成的。这就是为什么我要和我的同伴ChatGPT在一起,而不是让我忘记旧的Google的力量。另外,您的见解,反馈和共享经验将使这次冒险更加丰富和愉快。

the hobbit is running

在门口

没有两次思考,我在Chatgpt Plus上投入了20美元,然后转向了一个提示:给我一些我可以使用GO开发的数据工程领域的附带项目的想法。

我对购买常见和过度的东西没有兴趣,例如待办事项应用程序或网络刮板。此外,如果该项目与数据工程领域有关,那将是很棒的,这是我的专业领域。

尝试几次,我终于得到了一些引起我注意的东西。

Weather API

那么为什么这对我来说很有趣?

任何使用任何API都会导致HTTP请求,异常处理和JSON解析。此外,它为潜在的ETL/ELT流程打开了可能性,您可以在其中提取,转换和加载数据到某些数据库中的某些数据库。此外,您可以通过此数据创建引人入胜且有见地的可视化。

通常,这个想法听起来像是从不同角度探索语言的绝佳机会。之后,我要求Chatgpt几次,以获取有关如何利用天气API的更多详细信息,这给了我另一个很好的建议。

Climate Change Visualizer

然后我写了“详细介绍了气候变化的可视化器,那就是我得到的。

full plan for my future side project

如您所见,我为未来的Side项目制定了完整的计划,甚至建议我将来的进步。

potential future improvements

在我前面提到的文章中,还有另一个非常有价值的建议:思考较小。不要潜入一个需要50个小时才能完成的大型项目,而是尝试设想您可以在第2个小时内建立的东西。

所以,在我的传奇的第一部分中,我会牢记这个建议。我将专注于为GO语言项目创建本地环境并开发我的第一个脚本。该脚本将从公共天气API中获取一些数据为我即将到来的项目设定基础。

谈论公共天气API,我要求Chatgpt免费提供有关免费访问历史天气数据的最佳API建议。

best API to use for accessing historical weather data for free

由于这些API对我来说都不熟悉,所以我选择了第一个。如果还不够好,我可以在开发过程中任何时间更改它。

准备开发环境

安装去

要开始,我遵循官方GO website提供的说明,并将其作为MacOS用户安装,并为GO Workspace创建了一个文件夹:

mkdir ~/go

接下来,我需要指定GO Workspace(Gopath)的位置和在我的环境变量中安装GO可录(Gobin)的目录。我还将GO二进制目录添加到系统的路径变量中,以允许我从命令行中运行go命令和可执行文件,而无需指定其完整路径。

我编辑了我的zsh profile文件,位于〜/.zshrcâ

vi ~/.zshrc

export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOBIN

并重新加载了ZSH Shell的配置文件。

source ~/.zshrc

这些更改后,我可以从计算机上的任何终端运行GO命令。

go version command result

创建git仓库

对于我的项目,我显然需要一个公共GitHub存储库。我的意思是,谁会希望世界欣赏他们的出色想法和聪明的代码?

因此,我在我的GitHub帐户中创建了一个名为

Creating a new GitHub repo for my project

然后我复制了链接并将该项目克隆到我的计算机上。

Getting the link to my repo

git clone https://github.com/olgazju/weather-project.git

result of git clone

我必须承认,我喜欢使用GitHub Desktop来管理我的存储库。即使真正的程序员更喜欢命令行界面,并且像真正的Git向导一样掌握了它,但我对使用GitHub桌面时不会感到羞耻。它的视觉简单性和用户友好的体验使开发过程变得更加愉快,更具挑战性。

所以,我将天气项目文件夹添加为GitHub桌面中的现有存储库,并创建了API-CLI-Tool branch作为我的第一步。

api-cli-tool branch in Github Desktop

完成了这一重要步骤后,我全部设定了我的项目。

创建一个GO项目

我打开了Getting Started Go教程,它说:

在实际开发中,模块路径通常是保留源代码的存储库位置。例如,模块路径可能是github.com/mymodule。

好吧,正如建议的那样,我命名了我的模块github.com/weather-projectâ,然后从我的终端内部weather-project文件夹中的教程中运行下一个命令。

go mod init github.com/weather-project

the result of go mod init

终于是时候将其投入测试,看看我是否可以将VSCODE与GO Projects一起使用。

准备VSCODE

由于我曾经与VSCode一起作为我的可信赖IDE合作,因此我必须确认其与GO和GO项目的兼容性。

在VSCODE打开我的Weather-Project文件夹之前,我遇到了GO extension进行VSCODE并安装了它。

之后,我发现一个名为go.mod的新文件是为我创建的,当我运行go mod init命令时。当我进一步阅读时,我了解到该文件旨在跟踪提供这些软件包的模块。这听起来很合乎逻辑,因为它将有助于跟踪依赖关系并确保对项目的平稳管理。

Weather-project opened in VSCode

我决定测试我的设置,然后从经典开始,您好,World!”。老实说,我只是从教程中复制了“ Hello-World”代码,并创建了一个Hello.go。这是确保一切正常运行并能感觉运行基本GO程序的直接方法。

package main

import "fmt"
func main() {
    fmt.Println("Hello, World!")
}

之后,我在vscode终端中运行下一个命令。

go run .

Hello world script result

哇,它有效!

我还需要一件事让自己感到宾至如归,这通常与Python一起使用。使用数据时,我经常为了方便起见而转向Jupyter VScode extension。令我感到欣慰的是,我发现存在一个Go kernel,非常适合我的需求。

我在终端中运行以下命令,然后重新启动VSCODE。

go install github.com/janpfeifer/gonb@latest && go install golang.org/x/tools/cmd/goimports@latest && go install golang.org/x/tools/gopls@latest && gonb --install

Selecting Jupyter kernel

最后,我创建了一个新的jupyter notebook,并能够在其中选择GO内核。

Go kernel is available in my project

因此,我将我的“您好,World!”复制到Jupyter笔记本的第一个代码单元格中,然后运行它。一切看起来都不错。

Hello world result in Jupyter notebook

现在是在Go中写我自己的代码的那一刻。

正如Chatgpt所说的那样 - 我准备接受Go编程世界中未来的挑战和成长。真的讨厌这种过于热情的AI事物。我只是在去写作,我在这里不吃生日蛋糕。

CDO API

我遇到了Getting Started for chatgpt推荐的CDO API:

步骤1:请求令牌
为了访问CDO Web服务,必须首先从token request page获得令牌。

我遵循上面的令牌请求页面提供的说明,并通过电子邮件成功获得了我的令牌。因此,我准备继续将CDO API实施到我的GO项目中。

另一个提示:

prompt to ChatGPT

当然,我本来可以像在Go中写HTTP请求一样依靠Chatgpt中的提示,但是我宁愿采用更具控制的方法。有时,Chatgpt可能无法完全理解上下文或提供准确的信息。我也想理解代码而不是盲目复制。

我找到了一个示例,证明了在Go documentation中使用NET/HTTP软件包的用法。

为了控制HTTP客户端标头,重定向策略和其他设置,请创建一个客户端:
客户端:=&http.client {
checkredirect:redirectpolicyfunc,
}
req,err:= http.newrequest(“ get”,“ http://example.com”,nil)
// ...
req.header.add(“如果不匹配”,W/"wyzzy"
resp,err:= client.do(req)
// ...

Getting Started的端点部分中,我遇到了可用API端点的全面列表。

list of available API endpoints

因此,作为本章的第二步,我决定从CDO API获取所有可用数据集。

我在这个脚本中做了什么?

首先,我没有像文档中建议的那样创建客户端,我只是从http模块中使用了defaultclient对象。

我使用http.newrequest使用请求方法生成http.request值,然后将URL设置为数据集端点,即https://www.ncdc.noaa.gov/cdo-web/api/v2/datasets”,或者如果值可以可以处理错误被创建。

您可以看到,我使用http.defaultclient.do发送了创建的请求。如果您想使用实际令牌尝试此代码,请替换。

我在RESP变量中得到了响应。使用ioutil.ReadAll读取了dev.body,并且响应主体数据存储在身体变量中。

最后,使用fmt.println(string(body))打印响应主体。

我看到响应以 结果 字段中JSON形式的数据集列表的形式返回。尽管响应很大,但我会在这里分享一个片段,以给您一个想法:

{
   "metadata":{
      "resultset":{
         "offset":1,
         "count":11,
         "limit":25
      }
   },
   "results":[
      {
         "uid":"gov.noaa.ncdc:C00861",
         "mindate":"1763-01-01",
         "maxdate":"2023-06-05",
         "name":"Daily Summaries",
         "datacoverage":1,
         "id":"GHCND"
      },
...
]

我认为我想让JSON响应更易于管理和用户友好。我猜想我需要某种结构来匹配JSON的响应。

在我询问如何将JSON映射到变量的提示下,Chatgpt提出了一个涉及JSON.UNMARMARSHAL的建议。但是,它提供的示例代码没有得到理想的结果。我得到了下一个错误:

json: cannot unmarshal number 0.95 into Go struct field Dataset.results.datacoverage of type int

这是研究文档并探索types在GO中的概念以及如何执行JSON DATA unmarshaling的理想时刻。

因此,通过使用与结果JSON结构相匹配的适当字段来定义一个结构,我可以创建数据的结构化表示。使用json.unmarshal函数,我能够将JSON响应转换为相应的GO结构。

下面,您可以找到代码的更新版本:

我在代码中所做的事情:

所以我查看了JSON结构,除了``datacoverage''之外的所有字符都在这里。

{
   "uid":"gov.noaa.ncdc:C00861",
   "mindate":"1763-01-01",
   "maxdate":"2023-06-05",
   "name":"Daily Summaries",
   "datacoverage":1,
   "id":"GHCND"
}

然后,我定义了两种结构类型:数据集和数据集。数据集结构反映了JSON响应的结果字段,包括每个字段的相应数据类型。另一方面,数据集结构用作数据集对象的列表。

之后,我以与第一个脚本版本相同的方式发送了Get请求的方式,并且我使用JSON.unmarshal将结果字段匹配到数据集变量中的结果字段。然后,我使用一个循环在数据集变量的结果字段上迭代并打印每个数据集的名称字段。

您还可以观察错误处理机制:通过打印错误消息并从功能返回来处理错误。

正如预期的那样,我运行了代码,因此我得到了数据集名称的列表。

go run .

go run result

似乎每日摘要数据集可能是我们项目需求的合适候选人。

保存成就

成功创建了我的初始GO脚本(收到CDO API的回复)后,我决定是时候将更改推向存储库并合并我的分支。

此外,我确保使用.gitignore文件将.ds_store文件(这是MacOS特定文件)排除。仔细检查我的更改,将其推到我的分支机构。

Committing my changes

然后我向主分支打开了PR并将其合并。

Opening a PR

结论

在这一部分中,我对我的个人项目遇到了一个有趣的想法,这是我学习GO语言的旅程的一部分。我成功建立了本地开发环境,选择了天气API,并在Chatgpt的帮助下从中检索了一些数据。

完成了这些重要步骤,我现在准备继续进行项目。在下一部分中,我将重点探索和分析我从API获得的数据。继续跟随这次冒险,见证我在旅途中取得的进步。