这用于为列表中的每个人输出文档。但是,因为我添加了代码来确定最受欢迎的日期&对于给定日期列表的时间,它现在只为列表中的第一个人输出一个文档。
def save_thank_you_letters(id,form_letter)
Dir.mkdir("output") unless Dir.exists?("output")
filename = "output/thanks_#{id}.html"
File.open(filename,'w') do |file|
file.puts form_letter
end
end
puts "EventManager initialized."
contents = CSV.open 'event_attendees.csv', headers: true, header_converters: :symbol
template_letter = File.read "form_letter.erb"
erb_template = ERB.new template_letter
contents.each do |row|
id = row[0]
name = row[:first_name]
zipcode = clean_zipcode(row[:zipcode])
phone = clean_phonenumber(row[:homephone])
legislators = legislators_by_zipcode(zipcode)
form_letter = erb_template.result(binding)
save_thank_you_letters(id,form_letter)
# IT WORKS OK UNTIL I ADD THIS PART...
times = contents.map { |row| row[:regdate] }
target_times = Hash[times.group_by do |t|
DateTime.strptime(t, '%m/%d/%y %H:%M').hour
end.map do |k,v|
[k, v.count]
end.sort_by do |k,v|
v
end.reverse]
target_days = Hash[times.group_by do |t|
DateTime.strptime(t, '%m/%d/%y %H:%M').wday
end.map do |k,v|
[Date::ABBR_DAYNAMES[k], v.count]
end.sort_by do |k,v|
v
end.reverse]
puts target_times
puts target_days
end
我认为这与我处理日期/时间数据中的数据的方式有关。如果我删除它,我会为列表中的每个人获取一个html文档。但如果我加入它,我会得到日期&我正在寻找的时间信息 - 但它只为列表中的第一个人生成一个文档。
有人可以解释为什么我在做什么不起作用?我想打印一周的时间和日期,但也为列表中的每个人生成一个html文档。
谢谢!
答案 0 :(得分:0)
当您读取CSV文件时,您会逐行移动内部指针读取它。一旦你到达文件的末尾,这个指针就会停留在那里,所以每当你尝试获取新行时,除非你回卷文件,否则你将获得nil。所以,你的代码在这一行开始迭代:
contents.each do |row|
这会获取第一行并将光标移动到下一行。但是在循环内你做了contents.map {...}
,它读取了整个csv文件并将curses保留在文件的末尾。
所以要修复它,你需要在循环之外(之前或之后)移动统计位并在第二次迭代之前倒回文件(重置光标):
contents.each do |row|
id = row[0]
name = row[:first_name]
zipcode = clean_zipcode(row[:zipcode])
phone = clean_phonenumber(row[:homephone])
legislators = legislators_by_zipcode(zipcode)
form_letter = erb_template.result(binding)
save_thank_you_letters(id,form_letter)
end
contents.rewind
times = contents.map { |row| row[:regdate] }
target_times = Hash[times.group_by do |t|
DateTime.strptime(t, '%m/%d/%y %H:%M').hour
end.map do |k,v|
[k, v.count]
end.sort_by do |k,v|
v
end.reverse]
target_days = Hash[times.group_by do |t|
DateTime.strptime(t, '%m/%d/%y %H:%M').wday
end.map do |k,v|
[Date::ABBR_DAYNAMES[k], v.count]
end.sort_by do |k,v|
v
end.reverse]
puts target_times
puts target_days