Python 3 自定义日历项目缩进与排版异常问题排查
排查日历打印函数的换行异常问题
嘿,我帮你梳理下这段代码里导致排版换行不对的几个核心问题,咱们一步步拆解:
1. 重复填充开头空格,导致排版混乱
你代码里在for l in range(months[b]+1)循环内,每次打印日期前都执行sys.stdout.write((' ')*(int(z%7)))——这意味着每打一个日期就会重复补一次开头的空格!比如1号前面应该补对应星期数的空格,但2号、3号之后的日期根本不需要再补这个空格,直接跟在前面的日期后面就行。这种重复填充会让整个日历的列完全错位,换行自然就乱了。
2. 循环范围错误,包含无效的0日期
range(months[b]+1)会生成从0到当月天数的序列(比如31天的月份就是0-31),但实际日期是从1开始的。0这个无效日期不仅会被打印出来,还会干扰换行条件的判断,导致换行时机提前或错位。
3. 换行条件的计算逻辑有问题
当前的换行判断if (z+l)%7==0,其中z是当年1月1日的星期偏移,l是日期。但因为l包含了0,而且没有跟踪当前的星期位置,这个判断会导致换行时机完全不对。比如当l=0时,如果z%7==0,会直接换行,把标题和星期行之后的第一行空出来,后续日期的换行也会跟着乱。
4. 日期打印未做对齐处理
用print(l, end=' ')打印日期时,个位数日期(比如1)和两位数日期(比如10)占用的宽度不一样,会导致每列的宽度不一致,进而让整个日历的排版错位,换行看起来也异常。
5. 闰年判断后未更新2月天数
你代码里判断闰年之后给m=1,但并没有把2月的天数从28改成29,months[b]还是原来的28天,这样闰年2月的日期会少打印一天,同时也会影响整个月份的排版长度。
修正后的代码示例
我把这些问题都修正了,你可以参考下:
def year_month_calendar(a, b): # 定义各月份的默认天数 months = [31,28,31,30,31,30,31,31,30,31,30,31] month_str = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] import sys # 处理闰年,更新2月天数 if b == 2: if a % 400 == 0 or (a % 4 == 0 and a % 100 != 0): months[b-1] = 29 else: months[b-1] = 28 # 打印日历标题和星期表头 print(f"Calendar for {month_str[b-1]}, {a}") print('Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa') # 计算当年1月1日的星期偏移(这里假设0代表周日,可根据你的逻辑调整) leap_years = (a // 4) - (a // 100) + (a // 400) total_days = 365 * (a - 1) + leap_years # 如果有其他偏移量c,这里加上,确保是整数运算 # total_days += c current_week_day = total_days % 7 # 打印第一行开头的空格,每个星期列占3个字符(比如"Su ") print(' ' * (3 * current_week_day), end='') # 遍历当月所有有效日期 for day in range(1, months[b-1] + 1): # 格式化日期,占2位右对齐,后面加空格保证列宽一致 print(f"{day:2d} ", end='') current_week_day += 1 # 每到周六(星期数模7等于0)就换行 if current_week_day % 7 == 0: print() # 如果最后一行没填满7个日期,补一个换行让排版整洁 if current_week_day % 7 != 0: print()
关键修正点说明
- 只在日历第一行开头打印一次对应星期的空格,避免重复填充
- 循环从1开始遍历有效日期,去掉无效的0
- 用
current_week_day跟踪当前的星期位置,准确判断换行时机 - 用
f"{day:2d}"格式化日期,保证个位数和两位数日期占相同宽度,列对齐 - 闰年判断后直接更新2月的天数,确保日期数量正确
内容的提问来源于stack exchange,提问作者I need help
相关产品推荐
相关产品推荐

