Я использовал бы другой подход:
next
, чтобы получить следующую строку, и верните 3 строки , как это (я добавил комментарий, поскольку timeInRow
следует извлечь из row
, но ваш код не показывает его):
prev_row = [] # just in case it matches at first row
for row in csvFile:
# something must be done to extract timeInRow from row here!
if timeID == timeInRow:
return [prev_row,row,next(csvFile,[])]
prev_row = row # save current row for next iteration
next
использует значение пустого списка по умолчанию только в том случае, если строка last соответствует (исключает исключение StopIteration
)
Этот линейный подход работает, но если строки отсортированы по времени, и вам нужно выполнить несколько поисков, лучший подход (быстрее), вероятно, приведет к созданию списка строк, списка раз, затем используйте модуль bisect
для вычисления точки вставки в списке раз, убедитесь, что совпадение времени и использование индекса для возврата фрагмента списка строк.
Что-то вроде:
list_of_rows = list(csvFile)
list_of_times = [x[3] for x in list_of_rows] # assume that the time is the 4th column here
i = bisect.bisect(list_of_rows,timeInRow)
if i < len(list_of_rows) and list_of_rows[i] == timeInRow:
return list_of_rows[max(i-1,0):min(i+2,len(list_of_rows)]
Если вам нужно выполнить только 1 поиск, это происходит медленнее, вам все равно необходимо создать список O(n) + O(log(n))
. Но если вы хотите выполнить несколько поисков времени в том же списке, стоимость будет O(log(n))
за поиск.
Итак, я добавил в каждую строчку binding.pry, и он наконец щелкнул.
def email_notification(customer)
if customer.shipping_address_id.presence
@zipcode = Zipcode.find_by(zipcode: customer.shipping_address.zip)
@manager = @zipcode.region.region_email
if @manager.presence
CustomerMailer.notify_manager(customer, @manager).deliver_later
else
CustomerMailer.registration(customer).deliver_later
end
end
end
На самом деле это не электронная почта notify_manager, но это другая проблема.
Вы вызываете метод 'where' для экземпляра класса. И вам нужно сделать это против коллекции, и для этого вы должны сначала получить все адреса клиентов. Кстати, вы не оставили никакой информации о классе CustomerAddress.
Я могу предложить, что это должно быть что-то вроде этого:
@customer = Customer.find(name: 'Bob') # you found customer
@customer_addresses = @customer.shipping_address # you got customer addresses
Теперь вы можете сделать это @scoped_addresses = @customer_addresses.where('your query')
, но для этого вам нужно изменить направление ассоциации на наоборот. Клиент has_many :shipping_adresses, class_name: CustomerAddresses
И получить
@zip = @scoped_addresses.find('some criteria').shipping_zip
и далее вы можете перейти
@manager = Region.joins(:zipcodes).where(zipcodes: {zipcode: @zip}).manager
P.S. Было бы здорово, если бы вы ознакомились с доктриной