嵌套循环生成2D音乐列表问题:输出与预期不符求助
问题:生成符合规则的音乐序列数据失败
需求说明
- 用嵌套循环生成包含
[time,pitch,duration]的二维music_data列表 - 单序列时长1s、起始pitch60、结束pitch64时生成5个元素
- 重复2次时生成10个时间递增的元素
预期输出(重复2次时)
[ [0.0, 60, 0.2], [0.2, 61, 0.2], [0.4, 62, 0.2], [0.6, 63, 0.2], [0.8, 64, 0.2], [1.0, 60, 0.2], [1.2, 61, 0.2], [1.4, 62, 0.2], [1.6, 63, 0.2], [1.8, 64, 0.2] ]
实际输出
[0, 60, 0.5] [0.5, 61, 0.5] [1, 62, 0.5] [1.5, 63, 0.5]
原代码
def makeCrazyMusic(): global music_data ##### # # TODO: # - Ask for the crazy music parameters # - Clear the music list # - Use a nested loop to generate the crazy music in the music list # - Update the music summary # ##### #time = start time of note #pitch the pitch of note #durantion the length of the note #duration = duration / note --constant # = duration / startpitch -endpitch+1) #note = start pitch - end pitch +1 #time = time + duration #pitch = from start to end # try: times_input = int(turtle.numinput("Times to play", "Please enter number of times to play the sequence:")) dura_input = float(turtle.numinput("Duration", "Please enter duration to play the sequence:")) start_pitch = int(turtle.numinput("Start pitch", "Please enter Start pitch to play the sequence:")) end_pitch = int(turtle.numinput("End Pitch", "Please enter end pitch of the sequence:")) except TypeError: return music_data=[] #[time(+duration),pitch(nonc),duration(const)] index=0 for index in range(times_input): for pitch in (start_pitch,end_pitch+1): music_data.append([index,start_pitch,dura_input/times_input]) index= index+(dura_input/times_input) start_pitch= start_pitch+1 for x in range(len(music_data)): print(music_data[x])
问题分析
- 内层循环逻辑错误:
(start_pitch, end_pitch+1)是仅含两个元素的元组,导致内层循环只执行两次,无法遍历所有目标音高 - 时间计算逻辑错误:外层循环的
index是整数(来自range(times_input)),直接作为起始时间不符合时间递增规则;且修改循环变量index会打乱外层循环的执行 - 音高变量污染:直接修改
start_pitch会导致后续序列的起始音高被篡改,无法回到初始值 - 单音时长计算错误:应该用单序列总时长除以音高数量,而非除以重复次数
修正后的代码
import turtle def makeCrazyMusic(): global music_data try: times_input = int(turtle.numinput("Times to play", "Please enter number of times to play the sequence:")) seq_duration = float(turtle.numinput("Duration", "Please enter duration of a single sequence:")) base_start_pitch = int(turtle.numinput("Start pitch", "Please enter start pitch of the sequence:")) end_pitch = int(turtle.numinput("End Pitch", "Please enter end pitch of the sequence:")) except (TypeError, ValueError): return music_data = [] # 计算单个音符的时长:序列总时长 / 音高数量 note_count = end_pitch - base_start_pitch + 1 note_duration = seq_duration / note_count for seq_idx in range(times_input): # 计算当前序列的起始时间偏移 seq_start_time = seq_idx * seq_duration current_pitch = base_start_pitch current_time = seq_start_time # 遍历当前序列的所有音高 while current_pitch <= end_pitch: # 保留一位小数,匹配预期输出格式 music_data.append([round(current_time, 1), current_pitch, round(note_duration, 1)]) current_time += note_duration current_pitch += 1 # 打印结果 for item in music_data: print(item) # 可直接调用测试 # music_data = [] # makeCrazyMusic()
修正说明
- 内层循环改为
while current_pitch <= end_pitch,确保遍历所有目标音高 - 用
seq_start_time = seq_idx * seq_duration计算每个序列的起始时间,保证时间递增正确 - 保留原始起始音高
base_start_pitch,每次序列循环时重置current_pitch,避免音高偏移 - 正确计算单音时长:
note_duration = seq_duration / note_count,其中note_count是音高的总个数 - 增加
round函数保证时间和时长的小数位数整洁,匹配预期输出格式
内容的提问来源于stack exchange,提问作者Stephen Lai
相关产品推荐
相关产品推荐

