家庭收支记账软件

本文介绍了一个使用Go语言编写的家庭收支记账系统,从面向过程的实现逐步转变为面向对象的设计。系统包括显示主菜单、收支明细、登记收入和支出、退出确认等功能,并增加了登录验证。代码进行了优化,如用户退出时增加确认提示,无收支明细时的提示,以及账户余额检查等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

家庭收支记账系统

项目代码实现

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

编写文件 TestMyAccount.go 完成基本功能

  • 功能1:先完成可以显示主菜单,并且可以退出
    思路分析:
    根据给出的界面,完成主菜单的显示,当用户输入4时,就退出该程序
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.Print("请选择(1-4):")

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

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

  • 功能2:完成可以显示明细和登记收入的功能
    思路分析:
  1. 因为需要显示明细,我们定义一个变来给你details string来记录
  2. 我们还需要定义变量来记录余额(balance)、每次收支的金额(money)。每次收支的说明(note)
//定义账户余额【预设10000元余额】
	balance := 10000.0
	//每次收支的金额
	money := 0.0
	//每次收支的说明
	note := ""
	//收支的详情使用字符串来记录
	details := "收支\t账户金额\t收支金额\t说	明"

		case "2":
			fmt.Println("本次收入金额:")
			fmt.Scanln(&money)
			balance += money //修改账户余额
			fmt.Println("本次收入说明:")
			fmt.Scanln(&note)
			//将收入情况记录到details变量
			details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v", balance, money, note)
  • 功能3:完成了登记支出的功能
    思路分析:
    登记支出功能和登记收入功能类似,做些修改即可。
case "3":
			fmt.Println("本次支出金额:")
			fmt.Scanln(&money)
			//做一个判断
			if money > balance {
				fmt.Println("余额的金额不足")
				break
			}
			balance -= money //修改账户
			fmt.Println("本次支出说明:")
			fmt.Scanln(&note)
			details += fmt.Sprintf("\n支出\t%v\t\t%v\t\t%v", balance, money, note)

项目代码改进

  1. 用户输入4退出时,给出提示"你确定要退出吗?yn",必须输入正确的yn,否则循环输入指令,直到输入y或者n。
	case "4":
			fmt.Println("你确定要退出吗? y/n")
			choice := ""
			for {
				fmt.Scanln(&choice)
				if choice == "y" || choice == "n" {
					break
				} else {
					fmt.Println("你的输入有误,请重新输入 y/n")
				}
				if choice == "y" {
					loop = false
				}
			}
  1. 当没有任何收支明细时,提示"当前没有收支明细…来一笔吧!"
case "1":
			fmt.Println("-----------------当前收支明细记录-----------------")
			if flag {
				fmt.Println(details)
			} else {
				fmt.Println("当前没有收支明细... 来一笔吧!")
			}
  1. 在支出时,判断余额是否够,并给出相应的提示。
  2. 将面向过程的代码修改成面向对象的方法,编写myFamilyAccount…go,并使用testMyFamilyAccount…go去完成测试。
    思路分析:
    把记账软件的功能,封装到一个结构体中,然后调用该结构体的方法,来实现记账,显示明细。结构体的名字FamilyAccount
    通过在main方法中,创建一个FamilyAccount结构体实例,实现记账即可。
  • 面向过程
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.Print("请选择(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%v\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 += fmt.Sprintf("\n支出\t%v\t%v\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("你退出家庭记账软件的使用...")
}

  • 面向对象编程
  • utils/familyAccount
package utils

import "fmt"

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

// 编写一个工厂模式的构造方法,返回一个*FamilyAccount实例
func NewFamilyAccount() *FamilyAccount {
	return &FamilyAccount{
		//声明一个字段,保存接收用户输入的选项
		key: "",
		//声明一个字段,控制是否退出for循环
		loop: true,
		//定义账户
		balance: 10000.0,
		//每次收支的金额
		money: 0.0,
		//每次收支的说明
		note: "",
		//定义一个字段,记录是否有收支行为
		flag: false,
		//收支的详情使用字符串来记录
		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变量
	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("余额的金额不足")
		return
	}
	this.balance -= this.money //修改账户
	fmt.Println("本次支出说明:")
	fmt.Scanln(&this.note)
	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) quit() {
	fmt.Println("你确定要退出吗? y/n")
	choice := ""
	for {
		fmt.Scanln(&choice)
		if choice == "y" || choice == "n" {
			break
		} else {
			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.Print("请选择(1-4):")

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

		}
		if !this.loop {
			break
		}
	}
}

  • main.go
package main

import (
	"go_code/familyaccount/utils"
)

func main() {
	utils.NewFamilyAccount().MainMenu()

}

拓展功能

  1. 对上面的项目添加一个转账功能
  2. 在使用该软件前,有一个登录功能,只有输入正确的用户名和密码才能操作。
    familyaccount.go
package utils

import "fmt"

type FamilyAccount struct {
	//声明必要的字段
	//声明一个字段,保存接收用户输入的选项
	key string
	//声明一个字段,控制是否退出for循环
	loop bool
	//定义账户
	balance float64
	//每次收支的金额
	money float64
	//每次收支的说明
	note string
	//定义一个字段,记录是否有收支行为
	flag bool
	//收支的详情使用字符串来记录
	details string
	//定义用户名称
	UserName string
	//定义密码字段
	Pwd string
}

func (this *FamilyAccount) CheckUser(username string, pwd string) {
	for {
		fmt.Println("请输入用户名:")
		fmt.Scanln(&this.UserName)
		fmt.Println("请输入密码:")
		fmt.Scanln(&this.Pwd)
		if this.UserName != username && this.Pwd != pwd {
			fmt.Println("用户名或密码不正确,请重新输入...")
		} else {
			fmt.Println("登录成功,请稍候...")
			return
		}
	}
}

// 编写一个工厂模式的构造方法,返回一个*FamilyAccount实例
func NewFamilyAccount() *FamilyAccount {
	return &FamilyAccount{
		//声明一个字段,保存接收用户输入的选项
		key: "",
		//声明一个字段,控制是否退出for循环
		loop: true,
		//定义账户
		balance: 10000.0,
		//每次收支的金额
		money: 0.0,
		//每次收支的说明
		note: "",
		//定义一个字段,记录是否有收支行为
		flag: false,
		//收支的详情使用字符串来记录
		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变量
	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("余额的金额不足")
		return
	}
	this.balance -= this.money //修改账户
	fmt.Println("本次支出说明:")
	fmt.Scanln(&this.note)
	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) quit() {
	fmt.Println("你确定要退出吗? y/n")
	choice := ""
	for {
		fmt.Scanln(&choice)
		if choice == "y" || choice == "n" {
			break
		} else {
			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.Print("请选择(1-4):")

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

		}
		if !this.loop {
			break
		}
	}
}

main.go

package main

import (
	"go_code/chapter11/familyaccount/utils"
)

func main() {
	var account utils.FamilyAccount
	account.UserName = "tom"
	account.Pwd = "666666"
	utils.NewFamilyAccount().CheckUser(account.UserName, account.Pwd)
	utils.NewFamilyAccount().MainMenu()
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值