Python程序设计(第三版)课后题答案 第七章 [约翰·策勒 (著) 人民邮电出版社]

Python程序设计(第三版)课后题答案 第七章

编程练习题

  • 1.许多公司对每周超出40小时以上的工作时间支付150%的工资。编写程序输入工作小时数和小时工资,并计算一周的总工资。
    答案
def main():
    hour = eval(input('请输入周工作小时数:'))
    wage = eval(input('请输入每小时的工资:'))
    ecced = hour - 40
    if hour > 40:
        total_wages = 40 * wage + ecced * wage * 1.5
    else:
        total_wages = hour * wage
    print('一周总工资为:', total_wages)


main()

输出结果:

请输入周工作小时数:50
请输入每小时的工资:100
一周总工资为: 5500.0

进程已结束,退出代码0
  • 2.某位CS教授给出了5分的小测验,评分等级为5-A,4-B,3-C,2-D,1-E,0-F.编写一个程序,接受测验得分作为输入,并使用判断结构来计算相应的等级。
    答案
def main():   # 计算测验分数等级
    grade = input('请输入测验得分:')
    if grade == '5':
        print('分数等级为:A.')
    elif grade == '4':
        print('分数等级为:B.')
    elif grade == '3':
        print('分数等级为:C.')
    elif grade == '2':
        print('分数等级为:D.')
    elif grade == '1':
        print('分数等级为:E.')
    elif grade == '0':
        print('分数等级为:F.')
    else:
        print('输入无效,请重新输入0-5的数字!')


main()
请输入测验得分:5
分数等级为:A.

进程已结束,退出代码0
请输入测验得分:jnl
输入无效,请重新输入0-5的数字!

进程已结束,退出代码0
  • 3.某位CS教授给出了100分的考试,分级为90 ~ 100:A; 80 ~ 89:B; 70 ~ 79:C; 60~69:D; <60:F.编写一个程序将考试分数作为输入,并使用判断结构来计算相应的等级。
    答案
def main():   # 计算测验分数等级0-100
    grade = input('请输入测验得分:')

    try:
        g = int(grade) // 10
        if g == 10:
            print('考试等级为:A')
        elif g == 9:
            print('考试等级为:A')
        elif g == 8:
            print('考试等级为:B')
        elif g == 7:
            print('考试等级为:C')
        elif g == 6:
            print('考试等级为:D')
        else:
            print('考试等级为:F')
    except ValueError:
        print('值错误,请仔细检查程序输入!')


main()

输出结果如下:

请输入测验得分:88
考试等级为:B

进程已结束,退出代码0
请输入测验得分:adca
值错误,请仔细检查程序输入!

进程已结束,退出代码0
  • 4.某所大学根据学生拿到的学分对学生分年级。小于7学分的学生是大一新生。至少有7个学分才是大二,16分以上是大三,26分以上是大四。编写一个程序,根据获得的学分计算年级。
    答案
def main():  # 根据学分判断是大几学生
    grade = eval(input('请输入学生的学分:'))
    if grade < 7:
        print('大一新生!')
    elif 7 <= grade <= 16:
        print('大二学生!')
    elif 16 < grade <= 26:
        print('大三学生!')
    else:
        print('大四学生!')


main()

输出结果如下:

请输入学生的学分:5
大一新生!

进程已结束,退出代码0
请输入学生的学分:16
大二学生!

进程已结束,退出代码0
请输入学生的学分:27
大四学生!

进程已结束,退出代码0
  • 5.身体质量指数(BMI)的计算公式是人的体重(以磅计)乘以720,再除以人的身高(以英寸计)的平方。BMI在19-25范围内(包括边界值)被认为是健康的。编写一个程序,计算人的BMI,并打印一条消息,告诉他们实在健康范围之上,之中还是之下。
    答案
def main():  # 计算BMI,并判断是否在健康范围之内
    high = input('请输入要计算的身高(英寸):')
    weight = input('请输入要计算的体重(磅):')
    bmi = float(weight) * 720 / (float(high) ** 2)
    print("计算出的BMI为:", round(bmi,2))
    if 19 <= bmi <= 25:
        print('恭喜你!你的BMI在健康范围之内!')
    elif bmi < 19:
        print('注意身体哦!你的BMI在正常范围之下。')
    elif bmi > 25:
        print('注意身体哦!你的BMI在正常范围之上。')


main()

输出结果如下:

请输入要计算的身高(英寸):68
请输入要计算的体重(磅):156
计算出的BMI为: 24.29
恭喜你!你的BMI在健康范围之内!

进程已结束,退出代码0
  • 6.Podunksville的超速罚款政策是50美元加上超速部分每mph(一英里每小时)5美元,如果超过90mph再追加罚款200美元,编写一个程序,接受速度限制和计时速度,并打印一条消息,表明速度合法,或者在速度非法时,打印罚款。
    答案
def main():  # 判断速度是否合法,计算罚款
    speed_limit = eval(input('请输入限制速度(mph):'))
    speed_current = eval(input('请输入当前实时速度(mph):'))
    if speed_current > speed_limit:
        print('超速行驶!')
        if speed_current <= 90:
            fine = 50 + (speed_current - speed_limit) * 5
        else:
            fine = 250 + (speed_current - speed_limit) * 5
        print('应缴纳的罚款是:', fine)
    else:
        print('速度合法!')


main()

输出结果如下:

请输入限制速度(mph):45
请输入当前实时速度(mph):70
超速行驶!
应缴纳的罚款是: 175

进程已结束,退出代码0
请输入限制速度(mph):45
请输入当前实时速度(mph):40
速度合法!

进程已结束,退出代码0
  • 7.一个保姆每小时收费2.50美元直到晚上9:00,然后一小时降到1.75美元(孩子们在床上)。编写一个程序,接受以小时和分钟为单位的开始时间和结束时间,并计算总的保姆账单。可以假设开始和结束时间在一个24小时之内。不足一小时的应该适当的按比例分配。
    答案:
def main():  # 计算佣人工作时间计算费用
    total_wages = 0
    t1 = input('请输入开始工作时间(例如:8:00):')
    t2 = input('请输入结束工作时间(例如:8:00):')
    [sth, stm] = t1.split(':')
    [eth, etm] = t2.split(':')
    eh, sh, sm, em = int(eth), int(sth), int(stm), int(etm)
    if sh < 21 and eh <= 21:
        total_wages = (eh - sh - 1) * 2.5 + (60 - sm + em) * 2.5 / 60
    elif sh < 21 and eh >= 21:
        total_wages = (21 - sh - 1) * 2.5 + (60 - sm) * 2.5 / 60 + (eh - 21) * 1.75 + em * 1.75 / 60
    elif sh >= 21 and eh >= 21:
        total_wages = (eh - sh - 1) * 1.75 + (60 - sm + em) * 1.75 / 60
    print('总的账单为:', total_wages)


main()

输出结果如下:

请输入开始工作时间(例如:8:00):20:00
请输入结束工作时间(例如:8:00):22:00
总的账单为: 4.25

进程已结束,退出代码0
请输入开始工作时间(例如:8:00):8:00
请输入结束工作时间(例如:8:00):22:30
总的账单为: 35.125

进程已结束,退出代码0
  • 8.如果一个人至少30岁,并且成为美国公民至少9年,就有资格成为美国参议员。作为美国众议员,年限分别是25岁和7年。编写一个程序,接受一个人的年龄和公民年数作为输入,并输出他的参议院和众议院资格。
    答案:
def main():  # 根据年龄和公民年数判断资格
    age = eval(input('请输入要判断的年龄:'))
    year = eval(input('请输入公民年数:'))
    if age >= 30 and year >= 9:
        print("可以成为参议员!可以成为众议员!")
    elif age < 25 and year < 7:
        print('不可以成为参议员!也不可以成为众议员!')
    elif 25 <= age < 30 and 7 <= year < 9:
        print("可以成为众议员!不能成为参议员!")


main()

输出结果如下:

请输入要判断的年龄:26
请输入公民年数:8
可以成为众议员!不能成为参议员!

进程已结束,退出代码0
  • 9.计算1982~2048年的复活节计算公式如下所示:令a = year % 19, b = year % 4, c = year % 7,d = (19a + 24)%30,e = (2b + 4c + 6d + 5)%7。复活节的日期是3月22日 + d + e (可能在4月)。写一个程序,输入年份,验证它在适当的范围,然后打印出那一年复活节的日期。
    答案:
def main():  # 计算复活节的日期
    year = eval(input('请输入年份:'))
    a = year % 19
    b = year % 4
    c = year % 7
    d = (19 * a + 24) % 30
    e = (2 * b + 4 * c + 6 * d + 5) % 7
    s = d + e
    if 1982 <= year <= 2048:
        if s > 9:
            print('复活节的日期在4月{0}日。'.format(s - 9))
        else:
            print('复活节的日期在3月{0}日。'.format(22 + s))
    else:
        print('输入错误!请输入范围(1982~2048)内的年份!')


main()

输出结果如下:

请输入年份:2014
复活节的日期在420日。

进程已结束,退出代码0
请输入年份:2024
复活节的日期在331日。

进程已结束,退出代码0
请输入年份:2050
输入错误!请输入范围(1982~2048)内的年份!

进程已结束,退出代码0
  • 10.除1954年、1981年、2049年和2076年以外,上一个问题中复活节的公式适用于1900 - 2099年。对于这四年,它产生的日期晚了一个星期。修改上述程序,让它适用于1990 - 2099的所有年份。
    答案:
def main():  # 计算复活节的日期
    year = eval(input('请输入年份:'))
    a = year % 19
    b = year % 4
    c = year % 7
    d = (19 * a + 24) % 30
    e = (2 * b + 4 * c + 6 * d + 5) % 7

    if year == 1954 or year == 1981 or year == 2049 or year == 2076:
        s = d + e - 7
    else:
        s = d + e

    if 1900 <= year <= 2099:
        if s > 9:
            print('复活节的日期在4月{0}日。'.format(s - 9))
        else:
            print('复活节的日期在3月{0}日。'.format(22 + s))
    else:
        print('输入错误!请输入范围(1900~2099)内的年份!')


main()

输出结果如下:

请输入年份:1981
复活节的日期在419日。

进程已结束,退出代码0
请输入年份:2100
输入错误!请输入范围(1900~2099)内的年份!

进程已结束,退出代码0
  • 11.某年是闰年,如果它可以被4整除,除非它是世纪年份但不能被400整除(1800和1900不是闰年,而1600和2000是。)编写一个程序,计算某年是否为闰年。
    答案:
def main():  # 判断闰年
    year = eval(input('请输入年份:'))
    if year % 400 == 0:
        print("{0}是闰年!".format(year))
    elif year % 4 == 0 and year % 100 != 0:
        print('{0}是闰年!'.format(year))
    else:
        print('{0}不是闰年!'.format(year))


main()

输出结果如下:

请输入年份:1952
1952是闰年!

进程已结束,退出代码0
请输入年份:1900
1900不是闰年!

进程已结束,退出代码0
请输入年份:1600
1600是闰年!

进程已结束,退出代码0
  • 12.编写一个程序,以月/日/年的形式接受日期,并输出日期是否有效。例如5/24/1962是有效的,但9/31/2000不是。(9月只有30天。)
    答案:
def judge_leap_year(year):  # 判断闰年
    if year % 400 == 0:
        return True
    elif year % 4 == 0 and year % 100 != 0:
        return True
    else:
        return False


def main():  # 判断输入日期是否有效
    d = input('请输入日期(格式为:月/日/年):')
    dlist = d.split('/')
    sm = int(dlist[0])
    sd = int(dlist[1])
    sy = int(dlist[2])
    mlist = [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    dnlist = [31, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

    if 1900 <= sy <= 2099:
        if sm == 2:
            if judge_leap_year(sy):
                if 0 <= sd <= 29:
                    print('输入的日期{0}/{1}/{2}是有效的!'.format(sm, sd, sy))
                else:
                    print('输入日期的天数错误!')
            else:
                if 0 <= sd <= 28:
                    print('输入的日期{0}/{1}/{2}是有效的!'.format(sm, sd, sy))
                else:
                    print('输入日期的天数错误!')
        else:
            if 1 <= sm <= 12:
                for i in range(11):
                    if sm == mlist[i]:
                        if 0 <= sd <= dnlist[i]:
                            print('输入的日期{0}/{1}/{2}是有效的!'.format(sm, sd, sy))
                        else:
                            print('输入日期的天数错误!')
            else:
                print('输入日期的月份错误!')

    else:
        print('输入的年份超出范围(1900-2099)!')


main()
请输入日期(格式为:月//):9/31/2000
输入日期的天数错误!

进程已结束,退出代码0
请输入日期(格式为:月//):9/25/1982
输入的日期9/25/1982是有效的!

进程已结束,退出代码0
  • 13.一年中的第几天通常从1~365(或366)。这个数字可以用整数算术,利用三个步骤来计算:
    (a) dayNum = 31(mouth - 1) + day.
    (b) 如果月份是在二月之后减去(4(mouth)+23)//10.
    © 如果是闰年并在2月29号之后,加1.
    编写一个程序,以月/日/年的形式接受一个日期,验证它是一个有效的日期(见上一个问题),然后计算相应的天数。
    答案:
def judge_leap_year(year): 
    if year % 400 == 0:
        return True
    elif year % 4 == 0 and year % 100 != 0:
        return True
    else:
        return False


def judge_date_valid(sm, sd, sy):  # 判断输入日期是否有效

    mlist = [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    dnlist = [31, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

    if 1900 <= sy <= 2099:
        if sm == 2:
            if judge_leap_year(sy):
                if 0 <= sd <= 29:
                    print('输入的日期{0}/{1}/{2}是有效的!'.format(sm, sd, sy))
                    return True
                else:
                    print('输入日期的天数错误!')
                    return False
            else:
                if 0 <= sd <= 28:
                    print('输入的日期{0}/{1}/{2}是有效的!'.format(sm, sd, sy))
                    return True
                else:
                    print('输入日期的天数错误!')
                    return False
        else:
            if 1 <= sm <= 12:
                for i in range(11):
                    if sm == mlist[i]:
                        if 0 <= sd <= dnlist[i]:
                            print('输入的日期{0}/{1}/{2}是有效的!'.format(sm, sd, sy))
                            return True
                        else:
                            print('输入日期的天数错误!')
                            return False
            else:
                print('输入日期的月份错误!')
                return False

    else:
        print('输入的年份超出范围(1900-2099)!')
        return False


def main():  # 计算给定日期是一年内的第几天
    d = input('请输入日期(格式为:月/日/年):')
    dlist = d.split('/')
    sm = int(dlist[0])
    sd = int(dlist[1])
    sy = int(dlist[2])
    daynum = 0
    res = judge_date_valid(sm, sd, sy)
    if res and judge_leap_year(sy) and sm > 2:
        daynum = 31 * (sm - 1) + sd - (4 * sm + 23) // 10 + 1
    elif res and sm > 2:
        daynum = 31 * (sm - 1) + sd - (4 * sm + 23) // 10
    elif res:
        daynum = 31 * (sm - 1) + sd
  
    print('该日期是一年中的第{0}天!'.format(daynum))


main()

输出结果如下:

请输入日期(格式为:月//):3/1/2004
输入的日期3/1/2004是有效的!
该日期是一年中的第61天!

进程已结束,退出代码0
请输入日期(格式为:月//):2/1/2005
输入的日期2/1/2005是有效的!
该日期是一年中的第32天!

进程已结束,退出代码0
请输入日期(格式为:月//):3/1/2005
输入的日期3/1/2005是有效的!
该日期是一年中的第60天!

进程已结束,退出代码0
  • 14.做第4章中的编程练习7,但添加一个判断来处理直线不与圆相交的情况。
    答案:
def cricle_intersection(r, y):  # 函数的输入是圆的半径和截距
    win = GraphWin("Cricles_intersection", 600, 600)
    win.setCoords(-10, -10, 10, 10)
    win.setBackground("white")

    cricle = Circle(Point(0, 0), r)
    cricle.setOutline("black")
    cricle.draw(win)

    line = Line(Point(-10, y), Point(10, y))
    line.setOutline("black")
    line.draw(win)

    if -5 <= y <= 5:    # 添加判断结构
        x1 = sqrt(r ** 2 - y ** 2)  # 调用开平方函数计算x的正负值
        x2 = -x1

        p1 = Circle(Point(x1, y), 0.2)
        p1.setFill("red")
        p1.draw(win)
        pt1 = Text(Point(x1 + 1, y - 1), "x1")
        pt1.draw(win)
        p2 = Circle(Point(x2, y), 0.2)
        p2.setFill("red")
        p2.draw(win)
        pt2 = Text(Point(x2 - 1, y - 1), "x2")
        pt2.draw(win)

        print("x1 =", x1, "   x2 =", x2)
    else:
        pt = Text(Point(0, -9), "直线与圆没有交点")
        pt.setFill('red')
        pt.setSize(15)
        pt.draw(win)

    win.getMouse()
    win.close()


cricle_intersection(5, 3)  # 验证(5,3)和(5,-6)

输入结果如下:

在这里插入图片描述

x1 = 4.0    x2 = -4.0

进程已结束,退出代码0

在这里插入图片描述

  • 15.做第4章的编程练习8,但添加一个判断,以防止程序除以零,如果线是垂直的。
    答案:
def line_segment():
    win = GraphWin("line_segment", 600, 600)
    win.setCoords(0, 0, 100, 100)
    win.setBackground("white")

    p1 = win.getMouse()  # 通过点击获取点
    p1.draw(win)
    p2 = win.getMouse()
    p2.draw(win)
    x1 = p1.getX()  # 取出两点的坐标
    y1 = p1.getY()
    x2 = p2.getX()
    y2 = p2.getY()
    dx = x2 - x1
    dy = y2 - y1

    line = Line(Point(x1, y1), Point(x2, y2))  # 根据两点坐标绘制直线
    line.draw(win)

    c = Circle(Point((x1 + x2) / 2, (y1 + y2) / 2), 0.8)  # 绘制直线中点,用一个小圆代替,填充青色
    c.setFill("cyan")
    c.draw(win)
    if dx != 0:  # 添加判断结构,防止除以0
        slope = dy / dx  # 计算斜率
        length = sqrt(dx ** 2 + dy ** 2)  # 计算线段长度
        s = round(slope, 3)  # 分别保留三位小数
        lth = round(length, 3)
        print("slope=", s, "  length=", lth)
    else:
        slope = 1  # 计算斜率
        length = sqrt(dx ** 2 + dy ** 2)  # 计算线段长度
        lth = round(length, 3)   # 保留三位小数
        print("slope=", slope, "  length=", lth)

    win.getMouse()
    win.close()


line_segment()

输出结果如下:
在这里插入图片描述

slope= 1.339   length= 47.713

进程已结束,退出代码0
  • 16.射箭计分程序。编写一个绘制箭靶的程序(参见第4章的程序练习2),并允许用户点击五次以表示在目标处射击的箭头。采用五级评分,靶心(黄色)得9分,后续每个环减两分,直到白色为1分。该程序应输出每次点击的分数,并记录整个过程的动态总分。
    答案:
def calculate_bullseye_distance(p, c):  # 计算p点到靶心c点的距离
    dx = p.getX() - c.getX()
    dy = p.getY() - c.getY()
    d = sqrt(dx ** 2 + dy ** 2)
    return d


def main():  # 绘制同心环箭靶,计算得分
    win = GraphWin("箭靶", 600, 600)
    win.setCoords(0.0, 0.0, 100.0, 100.0)  # 将图像坐标统一为宽窄为100的方块
    shape = Circle(Point(50, 50), 25)  # 绘制最外侧圆
    shape.setOutline("white")
    shape.setFill("white")
    shape.draw(win)

    shape = Circle(Point(50, 50), 20)  # 绘制第四层圆
    shape.setOutline("black")
    shape.setFill("black")
    shape.draw(win)

    shape = Circle(Point(50, 50), 15)  # 绘制第三层圆
    shape.setOutline("blue")
    shape.setFill("blue")
    shape.draw(win)

    shape = Circle(Point(50, 50), 10)  # 绘制第二层圆
    shape.setOutline("red")
    shape.setFill("red")
    shape.draw(win)

    shape = Circle(Point(50, 50), 5)  # 绘制最内侧圆
    shape.setOutline("yellow")
    shape.setFill("yellow")
    shape.draw(win)

    pgrade = 0
    sgrade = 0
    for i in range(5):
        p = win.getMouse()
        pc = Circle(p, 0.5)  # 绘制弹着点
        pc.setOutline("green")
        pc.setFill("green")
        pc.draw(win)
        d = calculate_bullseye_distance(p, Point(50, 50))
        if d <= 5:
            pgrade = 9
        elif 5 < d <= 10:
            pgrade = 7
        elif 10 < d <= 15:
            pgrade = 5
        elif 15 < d <= 20:
            pgrade = 3
        elif 20 < d <= 25:
            pgrade = 1
        sgrade = sgrade + pgrade
        print('第{0}次射击得分为{1}分,累积总得分为{2}分。'.format(i+1, pgrade, sgrade))
    print('5次射击结束!')

    win.getMouse()
    win.close()


main()

输出结果如下:
在这里插入图片描述

1次射击得分为9分,累积总得分为9分。
第2次射击得分为7分,累积总得分为16分。
第3次射击得分为5分,累积总得分为21分。
第4次射击得分为3分,累积总得分为24分。
第5次射击得分为1分,累积总得分为25分。
5次射击结束!

进程已结束,退出代码0
  • 17.编写一个程序,用动画显示在窗口中弹跳的圆。基本思想是在窗口内部的某处启动圆。用变量dx和dy(都初始化为1)来控制圆的运动。采用大计数循环(例如10000次迭代),每次循环利用dx和dy移动圆。当圆心的x值过高(碰到边缘)时,将dx更改为-1。当它变得太低时,将dx更改为1。对dy使用类似的方法。(注意:你的动画可能运行的太快。你可以通过使用图形库的更新速率参数来减慢速度。例如,下面的循环将被限制,以每秒30次的速率执行:
    for i in range(100):

    update(30) # pause so rate is not more than 30 times a second)
    答案:
def main():  # 动态显示圆
    win = GraphWin("动态圆", 600, 600)
    win.setCoords(0.0, 0.0, 100.0, 100.0)  # 将图像坐标统一为宽窄为100的方块
    c = Circle(Point(10, 50), 10)  # 绘制最外侧圆
    c.setOutline("yellow")
    c.setFill("red")
    c.draw(win)

    dx, dy = 1, 1
    for i in range(2000):
        c.move(dx, dy)
        p = c.getCenter()
        if p.getY() == 90:
            dy = -1
        elif p.getX() == 90:
            dx = -1
        elif p.getY() == 10:
            dy = 1
        elif p.getX() == 10:
            dx = 1
        update(20)

    win.getMouse()
    win.close()


main()

输入结果如下:

Python生成窗口中运动的圆

  • 18.从上一章找一个最喜欢的编程问题,并根据需要添加判断和/或异常处理,让它真正健壮(不会因任何输入而崩溃)。
    答案: 程序中加入了try…except…结构,对于不符合规范的值都会进行提醒。
def calculat_area(a, b, c):  # 给定三边长,求三角形面积
    s = (a + b + c) / 2
    area = sqrt(s * (s - a) * (s - b) * (s - c))
    return area


def triangular_area():
    try:
        s1, s2, s3 = eval(input("请输入三角形的三个边长(例如:4,5,6):"))
        print('三角形的面积是:{0:0.2f}'.format(calculat_area(s1, s2, s3)))
    except:
        print('输入的值不符合规范!')


triangular_area()

输出如下:

请输入三角形的三个边长(例如:4,5,6):4,5,6
三角形的面积是:9.92

进程已结束,退出代码0
请输入三角形的三个边长(例如:4,5,6):1653116
输入的值不符合规范!

进程已结束,退出代码0
请输入三角形的三个边长(例如:4,5,6):、。,yjjb
输入的值不符合规范!

进程已结束,退出代码0




(如果错误,请读者批评指正!)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值