zoukankan      html  css  js  c++  java
  • go语言系列-家庭收支记账软件项目

    项目1 - 家庭收支记账软件项目

    项目开发流程说明

    项目需求说明

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

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

    项目的界面

    ---------------------家庭收支记账软件---------------------
                           
                           1 收支明细
                           2 登记收入
                           3 登记支出
                           4 退    出
    
                           请选择(1-4):1
    
    ---------------------当前收支明细记录---------------------
    收支          账户金额          收支金额          说明  
    
    ---------------------家庭收支记账软件---------------------
                           
                           1 收支明细
                           2 登记收入
                           3 登记支出
                           4 退    出
    
                           请选择(1-4):2
    本次收入金额: 1000
    本次收入说明: 有人发红包
                      
    ---------------------家庭收支记账软件---------------------
                           
                           1 收支明细
                           2 登记收入
                           3 登记支出
                           4 退    出
    
                           请选择(1-4):1
    ---------------------当前收支明细记录---------------------
    收支          账户金额          收支金额          说明  
    收入          1000              1000              有人发红包
    

    项目代码实现

    实现基本功能 - 面向过程

    功能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":
          case "3":
             fmt.Println("登记支出...")
          case "4":
             loop = false
          default:
             fmt.Println("请输入正确的选项...")
          }
          if !loop {
             break
          }
       }
       fmt.Println("你退出家庭记账软件的使用...")
    }
    

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

    思路分析:

    ​ 1) 因为需要显示明细,这里定义变量details string来记录

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

    func main()  {
       //声明一个变量,保存接收用户输入的选项
       key := ""
       //声明一个变量,控制是否退出for
       loop := true
    
       //定义账户的金额
       balance := 0.0
       //每次收支的金额
       money := 0.0
       //每次收支的说明
       note := ""
       //收支的详情使用字符串来记录
       //当有收支时,只需要对details 进行拼接处理即可
       details := "收支	账户金额	收支金额	说  明"
    
          case "1":
             fmt.Println("---------------------当前收支明细记录---------------------")
             fmt.Println(details)
          case "2":      //增加登记收入的处理
             fmt.Println("本次收入金额:")
             fmt.Scanln(&money)
             balance += money // 修改账户金额
             fmt.Println("本次收入说明:")
             fmt.Scanln(&note)
             //将收入情况,拼接到details变量
             details += fmt.Sprintf("
    收入	%v		%v		%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("
    支出	%v		%v		%v", balance, money, note)
    

    功能4:完成退出的功能

    思路分析:

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

     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
    }
    

    优化:当没有任何收支明细时,提示“当前没有收支明细... 来一笔吧!”

    func main()  {
       .....
       //定义个变量,记录是否有收支的行为
       flag := false
    	...... 
          switch key {
          case "1":
             fmt.Println("---------------------当前收支明细记录---------------------")
             if flag {
                fmt.Println(details)
             } else {
                fmt.Println("当前没有收支明细... 来一笔吧!")
             }
             //fmt.Println(details)
             fmt.Println()
    case "2":
            ......
    	flag = true
    

    总代码

    package main
    import (
    	"fmt"
    )
    func main() {
    	//声明一个变量,保存接收用户输入的选项
    	key := ""
    	//声明一个变量,控制是否退出for
    	loop := true
    
    	//定义账户的余额 []
    	balance := 10000.0
    	//每次收支的金额
    	money := 0.0
    	//每次收支的说明
    	note := ""
    	//定义个变量,记录是否有收支的行为
    	flag := false
    	//收支的详情使用字符串来记录
    	//当有收支时,只需要对details 进行拼接处理即可
    	details := "收支	账户金额	收支金额	说    明"
    	//显示这个主菜单
    	for {
    		fmt.Println("-----------------家庭收支记账软件-----------------")
    		fmt.Println("                  1 收支明细")
    		fmt.Println("                  2 登记收入")
    		fmt.Println("                  3 登记支出")
    		fmt.Println("                  4 退出软件")
    		fmt.Println("-----------------家庭收支记账软件-----------------")
    		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("
    收入	%v	%v	%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("
    支出	%v	%v	%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("你退出家庭记账软件的使用...")
    }
    

    实现基本功能 - 面向对象

    细细品味

    familyaccount.go

    package utils
    
    import "fmt"
    
    type FamilyAccount struct {
    	//声明必须的字段         可以看此处声明的字段和面向过程main函数中声明的字段是一致的
    
    	//声明一个变量,保存接收用户输入的选项
    	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: 0.0,
    		money: 0.0,
    		note: "",
    		flag: false,
    		details: "收支	账户金额	收支金额	说  明",
    	}
    }
    
    //将显示明细写成一个方法
    func (this *FamilyAccount) showDetails() {
    	fmt.Println("---------------------当前收支明细记录---------------------")
    	if this.flag {
    		fmt.Println(this.details)
    	} else {
    		fmt.Println("当前没有收支明细... 来第一笔吧!")
    	}
    	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("
    收入	%v		%v		%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("剩余的金额不足...")
    		//break
    	}
    	this.balance -= this.money
    	fmt.Println("本次支出说明:")
    	fmt.Scanln(&this.note)
    	this.details += fmt.Sprintf("
    支出	%v		%v		%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
    	}
    	fmt.Println("你退出家庭记账软件的使用...")
    }
    
    //给该结构体绑定相应的方法
    //显示主菜单
    func (this *FamilyAccount) MainMenu()  {
    	for {
    		fmt.Println("---------------------家庭收支记账软件---------------------")
    		fmt.Println("                        1 收支明细")
    		fmt.Println("                        2 登记收入")
    		fmt.Println("                        3 登记支出")
    		fmt.Println("                        4 退    出")
    		fmt.Println("---------------------家庭收支记账软件---------------------")
    		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.exit()
    		default:
    			fmt.Println("请输入正确的选项...")
    		}
    		if !this.loop {
    			break
    		}
    	}
    }
    
    

    main.go

    package main
    
    import (
    	"2020-04-08/utils"     //调用 NewFamilyAccount().MainMenu() 所在的包
    	"fmt"
    )
    
    func main()  {
    	fmt.Println("这个是用面向对象的方式完成的~")
    	//NewFamilyAccount() 工厂函数    MainMenu()菜单函数  通过调用菜单函数进而调用选项函数
    	utils.NewFamilyAccount().MainMenu() //思路非常清晰
    }
    

    可以明显的看到此项目是一次性的,如何做到持久化?
    写入数据库?写入文件

  • 相关阅读:
    border-sizing属性详解和应用
    初识scss:配置与运行
    详解scss的继承、占位符和混合宏
    详解promise、async和await的执行顺序
    JS调用模式
    自已写的线程池
    ThreadPool.QueueUserWorkItem的用法
    C#定时执行
    Task.Factory.StartNew的用法
    C#写文本日志帮助类(支持多线程)改进版(不适用于ASP.NET程序)
  • 原文地址:https://www.cnblogs.com/zisefeizhu/p/12658395.html
Copyright © 2011-2022 走看看