月初羊城通是否需要进行刷卡操作?

背景

     最近想到一个有趣的现象:羊城通在使用15次后才有优惠,到底前15次是否需要尽快使用低价进行刷次数?刷多少次后才是最优惠的?

针对以上两个问题,使用python进行计算,看看结果时怎样的?!

注:本算法只适应于当月乘坐地铁固定次数出行(即每月正常上下班路程次数与费用),对于不确定次数的不适用

算法实现:本算法用于实现工薪阶级,每月固定乘坐公交地铁上下班,计算每月最优惠出行费用

难点:在使用羊城通过程中,我们可以很容易就算出不使用刷卡次数当月的费用;但在使用刷卡次数后,每次刷卡后,总费用都存在变化;到底刷卡几次的总费用时最低的呢?

针对这个难点:

我们需要将这两种情况分别列举出来:

(1)当月不使用刷卡次数,即

总费用 = 15*一趟行程费用(打折前)+(当月出行次数-15)*一趟行程费用(打折后)

注:当月出行次数指的是一次乘坐地铁

(2)当月使用1—15次刷卡次数,即

总费用 = 刷卡次数 * 1.9 +(15 - 刷卡次数)*一趟行程费用(打折前)+(当月出行次数-15+i)*一趟行程费用(打折后)

注:公式中的1.9是广州地铁同站进出使用羊城通支付的最低费用,即刷次数当然就是选择最低费用进行

当我们明确算法时,我们就可以进行程序的编写了。

为了方便我们查看,这里我们引入matplotlib库生成折线图,方便查看

import numpy as np
from matplotlib import pyplot as plt

为了方便每人根据自己的情况查询,设置为手动输入当月出行次数、一趟行程费用(打折前)、一趟行程费用(打折后)的数据:

这里以我的情况为例:按工作日出行,记每月22个工作日,即每月出行次数:44次(来回),一趟行程费用(打折前):5.7元,一趟行程费用(打折后):3.6元

#输入当月出行次数
print('输入当月出行次数:')
trip_num = int(input())
#输入一趟行程费用(打折前)
print('输入一趟行程费用(打折前):')
trip_fee = float(input())
#输入一趟行程费用(打折后)
print('输入一趟行程费用(打折后):')
trip_fee_discnt = float(input())

 为了方便查看曲线变化,引用matplotlib库生成折线图

#声明全局变量
sum_trip_fee=0 #当月出行花费
sumMax_trip_fee=0 #当月出行最大花费
#定义一个函数,出行次数大于15则使用另一函数M
def function(x, x1, x2): # x1是分段点位置
    if x <= x1:
        return  x * trip_fee
    elif x <= x1 < x2:
        x1 * 1.9 + (x2 - x1) * trip_fee + (x - 15 + x2) * trip_fee_discnt
    else:
        return 15 * trip_fee + (x - 15) * trip_fee_discnt    
#根据次数进行函数计算
#当月正常使用,不进行刷次数操作所花费用
if trip_num <= 15:
    #如果当月乘坐地铁次数小于等于15次,生成函数图像
    sum_trip_fee = trip_num * trip_fee
    x = np.arange(0, 100, 1) #生成等差数组
    y = trip_num * x
    plt.xlabel('出行次数:x')
    plt.ylabel('出行费用:y')
    plt.title("出行次数与费用函数")
    plt.plot(x, y)
    plt.ylim(0, trip_num * trip_fee)   #限制y的范围
    plt.xlim(0, trip_num)   #限制x的范围
    plt.show()
    print('当月出行花费:'+str(sum_trip_fee))
    sumMax_trip_fee = sum_trip_fee
else:
    #当月乘坐地铁次数大于15次
    sum_trip_fee = 15 * trip_fee +(trip_num-15)*trip_fee_discnt
    x = np.arange(0, 100, 1) #生成等差数组
    y = np.array([function(t, 0, 15) for t in x]) #根据x计算各点函数值  
    plt.xlabel('出行次数:x')
    plt.ylabel('出行费用:y')
    plt.title("出行次数与费用函数")
    plt.plot(x, y)
    plt.ylim(0, trip_num * trip_fee)   #限制y的范围
    plt.xlim(0, trip_num)   #限制x的范围
    plt.show()
    print('当月出行花费:'+str(sum_trip_fee))
    sumMax_trip_fee = sum_trip_fee

按当月不使用刷卡次数,得到当月出行花费:189.9元

接下来,就需要将当月使用1—15次刷卡次数,得到的当月出行花费计算出来:

#进行刷卡费用
#进行循环比较,得出费用最好的刷卡数
num_swip = {}  
num_swips = {}   
num_swip.update({0: sum_trip_fee})
for i in range(1,16):
    if i <= 15:
        if trip_num + i <= 15:
            sum_trip_fee = i * 1.9 + trip_num * trip_fee
            num_swip.update({i: sum_trip_fee})
        else:
            sum_trip_fee = i * 1.9 +(15 - i)*trip_fee +(trip_num-15+i)*trip_fee_discnt
            num_swip.update({i: sum_trip_fee})
        print('当月刷卡次数:{0}次,出行花费{1}元'.format(str(i),str(sum_trip_fee)))
        i+=1

 最后,我们只需要将刷卡次数与当月出行花费存入到字典中,取出花费最少的值对于的刷卡次数,即可获取到当月刷卡次数多少次可得到当月出行最少花费

#自定义函数
def getKey(dic, value):
    if value not in dic.values():
        return None
    result = []
    for key in dic:
        if dic[key]==value:
            result.append(key)
    return result
#当月出行最大费用(即不使用刷卡次数的费用)
print('当月出行最大费用:'+str(sumMax_trip_fee))
#取出费用最少的刷卡次数
minValue=min(num_swip.values())
print('当月出行最少费用:'+str(minValue))
result = getKey(num_swip,minValue)
print('当月需刷卡次数:'+str(result[0]))
print('当月刷卡{0}次省了{1}块钱:'.format(str(result[0]),str(sumMax_trip_fee-minValue)))
if result[0] == 0:
    print('当月刷卡1次可省-1.9块钱)')
else:
    print('当月刷卡1次可省{0}块钱:'.format((sumMax_trip_fee-minValue)/result[0]))

最后的话:

通过这次的计算,我发现这个出行费用与出行次数与行程费用密切相关,当出行费用越大时,刷卡才有效,否则一味的刷卡,可能还不如不刷卡花费少;但有一个小窍门:当你的行程费用(打折前)与行程费用(打折后)金额大于你刷卡的金额,且你当月的出行次数大于15次时,你刷卡才不会亏!!!

注:本次算法经过少量数据验证可行,未对全部场景进行验证,如有遗漏,欢迎指教!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值