• MIT6.5830 Lab0-Go tutorial实验记录(四)


    MIT6.5830 Lab0-Go tutorial实验记录(四) – WhiteNight's Site

    Lab0的最后一步–对.csv文件进行查询。

    实验步骤

    更改handlers.go

    那么首先修改下handlers中的方法,毕竟现在不是从sqlite中查询数据了。

    1. // TODO: some code goes here
    2. // Get the chart data from RidershipDB
    3. db.Open("C:/Users/LENOVO/Desktop/Github/lab0/mbta.csv")
    4. chartdata, err := db.GetRidership(selectedChart)
    5. defer db.Close()

    仔细看下其他部分的代码,貌似都不用改,那么handlers处理完毕。

    实验步骤

    观察csv_ridership_db.go

    本次实验最难的地方来了。

    打开csv_ridership_db,可以看到Open函数已经很贴心的帮你写好了。而Close和GetRidership很明显要自己补齐了。

    Close很简单,直接csvFile.close,完事。

    1. // Close implements RidershipDB.
    2. func (c *CsvRidershipDB) Close() error {
    3. //panic("unimplemented")
    4. err := c.csvFile.Close()
    5. if err != nil {
    6. return err
    7. }
    8. return nil
    9. }

    但是GetRiderShip要补齐什么呢?没说。这里唯一的提示就是末尾的两行注释,但这两行注释一点用都没有

    1. // TODO: some code goes here
    2. // Implement the remaining RidershipDB methods

    那只能靠自己琢磨了。首先根据任务1在sqlite中执行查询的过程。GetRiderShip接收要查询的lineId,并且最后应该返回一个int64类型的切片。我们先读取sqlite打个断点看看这个返回的切片是什么。

    可以看到返回的直接就是xx线路分别在9个时间段的客流量。

    我们再对照一下SQL语句和csv文件。

    可以看到,total_ons就是xx线路在xx时间的xx站的客流量。direction?没用到。station_id?也没用到。那么我们要做的就是”根据time_period_xx,求xx线路在此时间的客流量总和,并且这个客流量和所在站台和线路的行驶方向无关“。

    有了个大概思路。我们接下来看看CsvRiderShip的代码。发现有个idIdxMap。我们先把GetRiderShip的返回值设为nil,然后打上断点看看它是干什么的

    可以看到idIdxMap是一个Map,其中key的类型为string,value的类型为int,而且key为时间间隔。那么我们可以想到:查询某个line的id,匹配之后根据Map的key将客流量插入Map对应的位置中。

    我们重新回到readme.md看看实验要求。

    1. Instead of issuing the query against sqlite, `CsvRidershipDB` directly runs it over the `mbta.csv` CSV file.
    2. MBTA divides a day into nine different time periods (*time_period_01*, ..., *time_period_09*). The CSV file contains how many passengers boarded trains during a specific time period, at a specific station and for a specific line and direction. For the queried line (passed to `GetRidership`) compute the total number of passengers that boarded a train for each given time period (for each time period, sum over all stations and directions). The sum for each time period should be an entry in the returned `int64` slice.
    3. Make sure to use the `idIdxMap` map to map the time period id strings (e.g. *time_period_01*) to the correct index in the `boardings` slice (e.g. 0).

    和我们的思路差不多,有了思路接下来就可以开始补全代码了。

    实验步骤

    补全CsvRiderShip

    先写个ReadALL把csv的内容转换为字符串。然后调试看看

    写者注

    从良了,再也不敢不写return err了。文章篇幅长点就长点吧,但是不写这个调试起来真的很麻烦。

    接下来新建个int64的切片,且长度为9,用来存储9个时间段的客流量。

    1. // GetRidership implements RidershipDB.
    2. func (c *CsvRidershipDB) GetRidership(lineId string) ([]int64, error) {
    3. //panic("unimplemented")
    4. boardings := make([]int64, c.num_intervals)
    5. records, err := c.csvReader.ReadAll()
    6. if records == nil {
    7. return nil, err
    8. }
    9. return ridershipData, nil
    10. }

    剩下的不就是写个for循环然后一行一行去匹配嘛,还是不难理解的。不过这里需要注意实验要求

    Make sure to use the `idIdxMap` map to map the time period id strings (e.g. *time_period_01*) to the correct index in the `boardings` slice (e.g. 0).

    idIdxMap的key就是时间段(“time_period_xx“),而对应的value为0-9,其实就是让你把idIdxMap[key]的值当boardings的下标用。该说是设计巧妙还是难以理解呢…可能两者都有吧。

    还有点需要注意的是,records[4]读取的total_one肯定是string类型的,需要转换为int类型的。因为最后返回的切片类型是int64,所以这里不能用strconv.Atoi,只能用strconv.PraseInt指定把它转换为int64的十进制数。

    1. // GetRidership implements RidershipDB.
    2. func (c *CsvRidershipDB) GetRidership(lineId string) ([]int64, error) {
    3. //panic("unimplemented")
    4. boardings := make([]int64, c.num_intervals)
    5. for {
    6. records, err := c.csvReader.Read()
    7. if err != nil {
    8. if err == io.EOF {
    9. break
    10. }
    11. return nil, err
    12. }
    13. if records[0] == lineId {
    14. sum, err := strconv.ParseInt(records[4], 10, 64)
    15. if err != nil {
    16. return nil, err
    17. }
    18. boardings[c.idIdxMap[records[2]]] += sum
    19. }
    20. }
    21. return boardings, nil
    22. }

    跑一下看看,浏览器输入localhost:8080,正常访问!第一次感觉到做完实验原来能这么爽。

    别忘了go test!

    实验总结

    Go:从入门到入门

    lab0的实验记录就到这里了。感觉go的旅途才刚刚开始…刚看了下后面几个lab,貌似是要实现一个DBMS,嗯…边做边学吧。

    要说学到了什么吧,主要是一些API的用法。还有断点和err这两个一定不能忘,调试就全靠这两个了。

  • 相关阅读:
    java八股文面试题
    无锁队列 SPSC Queue
    Zephyr是一个类似OSGI的Java插件框架
    七分钟,数据转换器get到了
    直播互动流程
    C/C++的内存管理
    用RocketMQ这么久,才知道消息可以这样玩
    【python基础】input函数
    神经网络前向和后向传播推导(一):概览
    流媒体技术基础-流媒体服务与框架
  • 原文地址:https://blog.csdn.net/white_night_SZTU/article/details/133925359