Все мы видели вот такую таблицу в семи нами "любимой" программе Revit :
Она отвечает за сортировку данных в спецификации, но в силу того что у нас только 4 возможных варианта сортировки данных мы не можем выполнить ряд задач. Таких как спецификация металлопроката или спецификация АС или банальная ведомость деталей. Кто нибудь задавался вопросом как это работает ?
Для полного понимания этой статьи конечно же необходимо понимание основ программирования. Я покажу лишь часть самого алгоритма без всякой чепухи , например как выдрать все нам необходимые данные из Revit и после обработки поместить в нужное место в том же Revit. Только математика и только логика.
Допустим у нас есть 8 арматурных стержней , разного диаметра , разного типа , разной длинны и количества. Попробуем отсортировать эти данные, и так у нас есть список длин:
ARMdlina=(1200,2000,2000,1200,3000,5000,1500,3000)
Теперь зададимся диаметрами:
ARMdiametr=(12,20,20,16,8,10,10,8)
Теперь нам необходимо отсортировать эти данные например по диаметру в порядке возрастания, тоесть если мыслить таблицей Revit то мы хотим получить такое :
И что же нам необходимо для выполнения такой простой сортировки ? ничего особенного , только знание полного синтаксиса Python или иного языка. Создадим функцию высшего порядка из булевого выражения:
new_list2 = [(c1,d1) for c1,d1 in zip(ARMdiametr,ARMdlina)]
Я думаю погуглив что есть ZIP в Python вы все поймете. Если выполнить кусок получившегося кода мы получим следующее:
Как видно мы просто объединили списки в одни. Каждый i-тый член списка сложился с j-тый членом второго списка. Теперь мы можем упорядочить элементы внутри списка как нам нужно.
А нам нужно просто узнать количество каждого типа с одинаковой длинной и диаметром и отсортировать по порядку все элементы. Для этого выполним двух уровневый цикл по новому списку new_list2 и будем отсеивать все повторяющиеся элементы и одновременно считать число их повторов (это и будет число экземпляров) , итак запишем код:
В итоге мы получили список количества каждого экземпляра [1, 2, 1, 2, 1] и сами экземпляры [(12, 1200), (20, 2000), (16, 1200), (8, 3000), (10, 5000)]. НО давайте пересчитаем изначальный список , в нем 8 элементов списка , а нам циклы вернули всего лишь 1+2+1+2+1=7, где то завалялся один элемент. этот элемент с диаметром 10 и длиной 1500. Он седьмой в первоначальной списке.
Не знаю на сколько я прав , но с точки зрения кода вроде все верно , нету "лозеек". Но один элемент потерялся. Я нашел этой проблеме решение , просто скопировал весь цикл еще раз и пособирал "яблоки" которые выпали из корзинки:
Как видно к нам вернулся блудливый сын и вся семья опять вместе.
Вот и сказочке конец :)
Она отвечает за сортировку данных в спецификации, но в силу того что у нас только 4 возможных варианта сортировки данных мы не можем выполнить ряд задач. Таких как спецификация металлопроката или спецификация АС или банальная ведомость деталей. Кто нибудь задавался вопросом как это работает ?
Для полного понимания этой статьи конечно же необходимо понимание основ программирования. Я покажу лишь часть самого алгоритма без всякой чепухи , например как выдрать все нам необходимые данные из Revit и после обработки поместить в нужное место в том же Revit. Только математика и только логика.
Допустим у нас есть 8 арматурных стержней , разного диаметра , разного типа , разной длинны и количества. Попробуем отсортировать эти данные, и так у нас есть список длин:
ARMdlina=(1200,2000,2000,1200,3000,5000,1500,3000)
Теперь зададимся диаметрами:
ARMdiametr=(12,20,20,16,8,10,10,8)
Теперь нам необходимо отсортировать эти данные например по диаметру в порядке возрастания, тоесть если мыслить таблицей Revit то мы хотим получить такое :
И что же нам необходимо для выполнения такой простой сортировки ? ничего особенного , только знание полного синтаксиса Python или иного языка. Создадим функцию высшего порядка из булевого выражения:
new_list2 = [(c1,d1) for c1,d1 in zip(ARMdiametr,ARMdlina)]
Я думаю погуглив что есть ZIP в Python вы все поймете. Если выполнить кусок получившегося кода мы получим следующее:
Как видно мы просто объединили списки в одни. Каждый i-тый член списка сложился с j-тый членом второго списка. Теперь мы можем упорядочить элементы внутри списка как нам нужно.
А нам нужно просто узнать количество каждого типа с одинаковой длинной и диаметром и отсортировать по порядку все элементы. Для этого выполним двух уровневый цикл по новому списку new_list2 и будем отсеивать все повторяющиеся элементы и одновременно считать число их повторов (это и будет число экземпляров) , итак запишем код:
В итоге мы получили список количества каждого экземпляра [1, 2, 1, 2, 1] и сами экземпляры [(12, 1200), (20, 2000), (16, 1200), (8, 3000), (10, 5000)]. НО давайте пересчитаем изначальный список , в нем 8 элементов списка , а нам циклы вернули всего лишь 1+2+1+2+1=7, где то завалялся один элемент. этот элемент с диаметром 10 и длиной 1500. Он седьмой в первоначальной списке.
Не знаю на сколько я прав , но с точки зрения кода вроде все верно , нету "лозеек". Но один элемент потерялся. Я нашел этой проблеме решение , просто скопировал весь цикл еще раз и пособирал "яблоки" которые выпали из корзинки:
Как видно к нам вернулся блудливый сын и вся семья опять вместе.
Вот и сказочке конец :)
Выполнять цикл for по списку, в котором при этом удаляются элементы не самая лучшая идея, так как for создаёт итератор, по каждому члену которого и проходится, т.е. при удалении первого элемента списка цикл начнёт следующую итерацию не сначала, а со второго элемента, поэтому и происходит выпадение элементов. Можно попробовать решить через while. Например, так:
ОтветитьУдалитьcnt, nm = [], []
nm_i = tuple()
while new_list2:
cnt.append(new_list2.count(new_list2[0]))
i = new_list2[0]
nm.append(i)
while i in new_list2:
new_list2.remove(i)
print(cnt)
print(nm)
С отступами
ОтветитьУдалитьhttp://joxi.ru/KAxzK5dI4RyMMm
ок ,спасибо
Удалитьну он не совсем выпадает , он просто не доходит до конца списка, через For я и создал так чтобы он выдрал все повторяющиеся элементы и опять начал с начала , но я так понимаю когда он доходит до момента когда в списке всего лишь один элемент он останавливается в итоге еще одним циклом я добираю "остатки". Еще не посмотрел ваш вариант но через while пробовал когда то.
ОтветитьУдалить