[go学习笔记.第十一章.项目案例] 1.家庭收支记账软件项目

一.基本介绍

1.项目开发流程说明

2.项目需求说明

目标:

模拟实现一个基于文本界面的<<家庭记账软件>>

掌握初步的编程技巧和调试技巧

主要涉及以下知识点 :

(1).局部变量和基本数据类型

(2).循环语句

(3).分支语句

(4).简单的屏幕输出格式控制

(5).进阶:面向对象编程使用

需求说明

模拟实现基于文本界面的 《 家庭记账软件 》

该软件能够记录家庭的收入、支出,并能够打印收支明细表 

项目采用分级菜单方式,主菜单如下:

3.项目界面

(1).收支明细界面

(2).登记收入界面 

(3).登记支出界面 

 (4).退出界面

二.代码实现

1. 实现基本功能(先使用面向过程,后面改成面向对象)

功能1:   

        先完成可以显示主菜单,并且可以退出

思路分析: 

        显示给出的主界面,主菜单的显示,当用户输入 4 时,就退出该程序

功能2:

        完成可以显示明细和登记收入的功能

思路分析:

        (1).因为需要显示明细,我们定义一个变量details来记录

        (2).还需要定义变量来记录余额(balance)、每次收支的金额(money),每次收支的说明(note)

功能 3:

        完成登记支出的功能

思路分析:

        登记支出的功能和登录收入的功能类似,做些修改即可

功能1:   先完成可以显示主菜单,并且可以退出

package main

import (
    "fmt"
)

func main() {
    //声明一个变量,保存接收用户输入的选项
    key := ""
    //声明一个变量,控制是否退出for
    loop := true
    //显示主菜单
    for {
        fmt.Println("----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&key)

        switch key {
        case "1":
            fmt.Println("----------------当前收支明细------------------")
        case "2":
        case "3":
            fmt.Println("登记支出")
        case "4":
            loop = false
        default :
            fmt.Println("请输入正确的选项")       
        }

        if !loop {
            break
        }
    }

    fmt.Println("你退出了家庭收支记账软件的使用")
}

功能2: 完成可以显示明细和登记收入的功能

package main

import (
    "fmt"
)

func main() {
    //声明一个变量,保存接收用户输入的选项
    key := ""
    //声明一个变量,控制是否退出for
    loop := true
    //定义账户余额
    balance := 10000.0
    //每次收支的金额
    money := 0.0
    //每次收支的说明
    note := ""
    //收支的详情使用字符串来记录
    //当有收支时,只需要对details进行拼接处理即可
    details := "收支\t账号余额\t收支金额\t说   明"
    //显示主菜单
    for {
        fmt.Println("\n----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&key)

        switch key {
        case "1":
            fmt.Println("----------------当前收支明细------------------")
            fmt.Println(details)
        case "2":
            fmt.Println("本次收入金额:")
            fmt.Scanln(&money)
            balance += money    //修改账户余额
            fmt.Println("本次收入说明:")
            fmt.Scanln(&note)
            //将这个收入情况,拼接到details变量
            //收入 11000 1000 有人发红包
            details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v",balance, money, note)

        case "3":
            fmt.Println("登记支出")
        case "4":
            loop = false
        default :
            fmt.Println("请输入正确的选项") 
        }

        if !loop {
            break
        }
    }

    fmt.Println("你退出了家庭收支记账软件的使用")
}

功能 3:  完成登记支出的功能

package main

import (
    "fmt"
)

func main() {
    //声明一个变量,保存接收用户输入的选项
    key := ""
    //声明一个变量,控制是否退出for
    loop := true
    //定义账户余额
    balance := 10000.0
    //每次收支的金额
    money := 0.0
    //每次收支的说明
    note := ""
    //收支的详情使用字符串来记录
    //当有收支时,只需要对details进行拼接处理即可
    details := "收支\t账号余额\t收支金额\t说   明"
    //显示主菜单
    for {
        fmt.Println("\n----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&key)

        switch key {
        case "1":
            fmt.Println("----------------当前收支明细------------------")
            fmt.Println(details)
        case "2":
            fmt.Println("本次收入金额:")
            fmt.Scanln(&money)
            balance += money    //修改账户余额
            fmt.Println("本次收入说明:")
            fmt.Scanln(&note)
            //将这个收入情况,拼接到details变量
            //收入 11000 1000 有人发红包
            details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v",balance, money, note)
        case "3":
            fmt.Println("本次支出金额:")
            fmt.Scanln(&money)
            //这里需要做一个判断
            if money > balance {
                fmt.Println("支出的余额不足")
                break
            }
            balance -= money    //修改账户余额
            fmt.Println("本次支出说明:")
            fmt.Scanln(&note)
            //将这个支出情况,拼接到details变量
            //支出 11000 1000 吃中午饭
            details += fmt.Sprintf("\n支出\t%v\t\t%v\t\t%v",balance, money, note)
        case "4":
            loop = false
        default :
            fmt.Println("请输入正确的选项")  
        }

        if !loop {
            break
        }
    }

    fmt.Println("你退出了家庭收支记账软件的使用")
}

2.项目代码改进

(1).用户输入 4 退出时,给出提示”你确定要退出吗? y / n " ,必须输入正确的 y / n 指令,否则循环输入,直到输入 y 或者 n 

(2).当没有任何收支明细时,提示”当前没有收支明细 … 来一笔吧!"

(3).在支出时,判断余额是否够,并给出相应的提示

package main

import (
    "fmt"
)

func main() {
    //声明一个变量,保存接收用户输入的选项
    key := ""
    //声明一个变量,控制是否退出for
    loop := true
    //定义账户余额
    balance := 10000.0
    //每次收支的金额
    money := 0.0
    //每次收支的说明
    note := ""
    //定义一个变量,记录是否有收支的行为
    flag := false
    //收支的详情使用字符串来记录
    //当有收支时,只需要对details进行拼接处理即可
    details := "收支\t账号余额\t收支金额\t说   明"
    //显示主菜单
    for {
        fmt.Println("\n----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&key)

        switch key {
        case "1":
            fmt.Println("----------------当前收支明细------------------")
            if flag {
                fmt.Println(details)
            } else {
                fmt.Println("当前没有收支明细,来一笔")
            }
        case "2":
            fmt.Println("本次收入金额:")
            fmt.Scanln(&money)
            balance += money    //修改账户余额
            fmt.Println("本次收入说明:")
            fmt.Scanln(&note)
            //将这个收入情况,拼接到details变量
            //收入 11000 1000 有人发红包
            details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v",balance, money, note)
            flag = true
        case "3":
            fmt.Println("本次支出金额:")
            fmt.Scanln(&money)
            //这里需要做一个判断
            if money > balance {
                fmt.Println("支出的余额不足")
                break
            }
            balance -= money    //修改账户余额
            fmt.Println("本次支出说明:")
            fmt.Scanln(&note)
            //将这个支出情况,拼接到details变量
            //支出 11000 1000 吃中午饭
            details += fmt.Sprintf("\n支出\t%v\t\t%v\t\t%v",balance, money, note)
            flag = true
        case "4":
            fmt.Println("你确定要退出吗? y/n")
            choice := ""
            for {
                fmt.Scanln(&choice)
                if choice == "y" || choice == "n" {
                    break
                }
                fmt.Println("你输入有误,请重新输入 y/n")  
            }
            if choice == "y" {
                loop = false
            }
        
        default :
            fmt.Println("请输入正确的选项")
        }

        if !loop {
            break
        }
    }

    fmt.Println("你退出了家庭收支记账软件的使用")
}

(4).将面向过程的代码修改成面向对象的方法,编写myFamilyAccount.go,并使用 testMyFamilyAccount.go 去完测试

思路分析:

        把记账软件的功能,封装到一个结构体中,然后调用该结构体的方法,来实现记账,显示明细。结构体的名字 FamilyAccount,在通过main方法中,创建一个结构体FamilyAccount实例,实现记账即可,码不需要重写,只需要重写组织一下

myFamilyAccount.go

package utils

import (
    "fmt"
)

type FamilyAccount struct {
    //声明必要的字段
    //声明一个字段,保存接收用户输入的选项
    key string
    //声明一个字段,控制是否退出for
    loop bool
    //定义账户余额
    balance float64
    //每次收支的金额
    money float64
    //每次收支的说明
    note string
    //定义一个字段,记录是否有收支的行为
    flag bool
    //收支的详情使用字符串来记录
    //当有收支时,只需要对details进行拼接处理即可
    details string
} 

//编写一个工厂模式的构造方法,返回一个*FamilyAccount实例
func NewFamilyAccount() *FamilyAccount  {
    return &FamilyAccount {
        key : "",
        loop : true,
        balance : 10000.0,
        money : 0.0,
        note : "",
        details : "收支\t账号余额\t收支金额\t说    明",
    }
}
//将显示明细写成一个方法
func (this *FamilyAccount) showDetails() {
    fmt.Println("----------------当前收支明细------------------")
    if this.flag {
        fmt.Println(this.details)
    } else {
        fmt.Println("当前没有收支明细,来一笔")
    }
}

//将登记收入写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) income()  {
    fmt.Println("本次收入金额:")
    fmt.Scanln(&this.money)
    this.balance += this.money  //修改账户余额
    fmt.Println("本次收入说明:")
    fmt.Scanln(&this.note)
    //将这个收入情况,拼接到details变量
    //收入 11000 1000 有人发红包
    this.details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v", this.balance, this.money, this.note)
    this.flag = true
}

//将登记支出写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) pay()  {
    fmt.Println("本次支出金额:")
    fmt.Scanln(&this.money)
    //这里需要做一个判断
    if this.money > this.balance {
        fmt.Println("支出的余额不足")
    }
    this.balance -= this.money  //修改账户余额
    fmt.Println("本次支出说明:")
    fmt.Scanln(&this.note)
    //将这个支出情况,拼接到details变量
    //支出 11000 1000 吃中午饭
    this.details += fmt.Sprintf("\n支出\t%v\t\t%v\t\t%v", this.balance, this.money, this.note)
    this.flag = true
}

//将退出写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) exit()  {
    fmt.Println("你确定要退出吗? y/n")
    choice := ""
    for {
        fmt.Scanln(&choice)
        if choice == "y" || choice == "n" {
            break
        }
        fmt.Println("你输入有误,请重新输入 y/n")  
    }
    if choice == "y" {
        this.loop = false
    }
}

//给结构体绑定方法
//显示主菜单
func (this *FamilyAccount) MainMenu() {
    for {
        fmt.Println("\n----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&this.key)

        switch this.key {
        case "1":
            this.showDetails()
        case "2":
            this.income()
        case "3":
            this.pay()
        case "4":
            this.exit()
        default :
            fmt.Println("请输入正确的选项") 
        }

        if !this.loop {
            break
        }
    }
    fmt.Println("你退出了家庭收支记账软件的使用")
}

main.go

package main

import (
    "fmt"
    "go_code/familyAccount/utils"
)

func main() {
    fmt.Println("面向对象方式实现")
    utils.NewFamilyAccount().MainMenu()
}

对项目的扩展功能:

        1.对上面的项目完成一个转账功能

        2.使用该软件前,有一个登录功能,只有输入正确的用户名,密码才能操作

 myFamilyAccount.go

package utils

import (
    "fmt"
)

type FamilyAccount struct {
    //声明必要的字段
    //声明一个字段,保存接收用户输入的选项
    key string
    //声明一个字段,控制是否退出for
    loop bool
    //定义账户余额
    balance float64
    //每次收支的金额
    money float64
    //每次收支的说明
    note string
    //定义一个字段,记录是否有收支的行为
    flag bool
    //收支的详情使用字符串来记录
    //当有收支时,只需要对details进行拼接处理即可
    details string

    //定义用户名
    name string
    //定义用户密码
    pwd string
} 

//编写一个工厂模式的构造方法,返回一个*FamilyAccount实例
func NewFamilyAccount() *FamilyAccount  {
    return &FamilyAccount {
        key : "",
        loop : true,
        balance : 10000.0,
        money : 0.0,
        note : "",
        details : "收支\t账号余额\t收支金额\t说    明",
    }
}

//将显示明细写成一个方法
func (this *FamilyAccount) showDetails() {
    fmt.Println("----------------当前收支明细------------------")
    if this.flag {
        fmt.Println(this.details)
    } else {
        fmt.Println("当前没有收支明细,来一笔")
    }
}

//将登记收入写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) income()  {
    fmt.Println("本次收入金额:")
    fmt.Scanln(&this.money)
    this.balance += this.money  //修改账户余额
    fmt.Println("本次收入说明:")
    fmt.Scanln(&this.note)
    //将这个收入情况,拼接到details变量
    //收入 11000 1000 有人发红包
    this.details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v", this.balance, this.money, this.note)
    this.flag = true
}

//将登记支出写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) pay()  {
    fmt.Println("本次支出金额:")
    fmt.Scanln(&this.money)
    //这里需要做一个判断
    if this.money > this.balance {
        fmt.Println("支出的余额不足")
    }
    this.balance -= this.money  //修改账户余额
    fmt.Println("本次支出说明:")
    fmt.Scanln(&this.note)
    //将这个支出情况,拼接到details变量
    //支出 11000 1000 吃中午饭
    this.details += fmt.Sprintf("\n支出\t%v\t\t%v\t\t%v", this.balance, this.money, this.note)
    this.flag = true
}

//将退出写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) exit()  {
    fmt.Println("你确定要退出吗? y/n")
    choice := ""
    for {
        fmt.Scanln(&choice)
        if choice == "y" || choice == "n" {
            break
        }
        fmt.Println("你输入有误,请重新输入 y/n")  
    }
    if choice == "y" {
        this.loop = false
    }
}

//将判断用户登录写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) login() {
    for {
        fmt.Println("请输入用户名:")
        fmt.Scanln(&this.name)
        fmt.Println("请输入密码:")
        fmt.Scanln(&this.pwd)
        if this.name == "root" && this.pwd == "123456" {
            break 
        }
        fmt.Println("用户名或密码错误,请重新输入")
    }
}

//给结构体绑定方法
//显示主菜单
func (this *FamilyAccount) MainMenu() {
    this.login() 
    for {
        fmt.Println("\n----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&this.key)

        switch this.key {
        case "1":
            this.showDetails()
        case "2":
            this.income()
        case "3":
            this.pay()
        case "4":
            this.exit()
        default :
            fmt.Println("请输入正确的选项")    
        }

        if !this.loop {
            break
        }
    }
    fmt.Println("你退出了家庭收支记账软件的使用")
}

[上一节]go学习笔记.第十章.面向对象编程] 12.类型断言引出和基本使用

[下一节][go学习笔记.第十一章.项目案例] 2.客户信息管理系统 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《Go语言学习笔记.pdf》是一本关于Go语言学习学习笔记,内容丰富且简洁明了。本书从基础知识开始,逐步介绍了Go语言的语法、特性和常用库函数等。在学习笔记中,作者通过实际的示例和练习帮助读者理解Go语言的概念和用法。 第一章介绍了Go语言的起源和发展,为读者提供了对Go语言背景的整体了解。第二章讲解了Go语言的基本语法,例如变量声明、循环和条件语句等。通过大量的代码示例,读者能够更好地理解Go语言的语法和结构。 接下来的章节重点介绍了Go语言的并发编程和高级特性。第三章详细介绍了Go语言中的goroutine和channel,这是Go语言并发编程的核心机制。作者通过生动的示例代码和实际应用案例,向读者展示了如何使用goroutine和channel实现并发编程。 第四章和第五章分别介绍了Go语言中的面向对象编程和函数式编程。通过深入讲解Go语言中的结构体、接口和函数,读者能够更好地应用这些特性进行代码设计和开发。 最后几章则介绍了Go语言中常用的库函数和工具。例如,第六章介绍了Go语言中用于网络编程的net包和http包。读者可以学习到如何使用这些库函数构建基于网络的应用程序。 总的来说,《Go语言学习笔记.pdf》是一本非常实用的Go语言学习资料。通过阅读这本书,读者能够系统地学习和理解Go语言的基本概念和高级特性,为之后的Go语言开发打下坚实的基础。无论是初学者还是有一定编程经验的开发者,都能从中获得丰富的知识和经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值