Loading...

Във форума е въведено ограничение, което позволява на потребителите единствено да разглеждат публикуваните въпроси.

achobanov avatar achobanov -4 Точки

Голямата практична задача от работилницата

Здравейте. Днес цял ден се бъхтих и написах от нулата някакво решение, използващо обекти. До колко работи правилно не знам, но на принтване го докарвам. Стойностите ми са подозрително близки, но всъшност това може би е нормално за големи статистики? Знам ли. Освен това не знам дали е нормално на програмата ми да й отнема околко 3 минути ( Intel  i5-3210M, dual core ) да прекара файла с 1млн продажби. Ето и резултатите, които получавам:

Обобщение
---------
    Общ брой продажби: 1000000
    Обща сума продажби: 316698926.08
    Средна цена на продажба: 316.69892608
    Начало на период на данни: 2015-12-01 08:00:00+02:00
    Край на период на данни: 2016-01-24 20:59:56+00:00
            

Сума на продажби по категории (top 5)
-----------------------------
    JACKETS, SURFING  :****************************** 3010983.13 $
    T-SHIRTS, WORKOUT :***************************** 3004242.26 $
    SHOES, GOLF       :***************************** 3001690.56 $
    SHOES, WRESTLING  :***************************** 3000527.93 $
    SHOES, BOXING     :***************************** 2998642.42 $
            

Сума на продажби по градове (top 5)
---------------------------
    Manchester :****************************** 8697704.85 $
    Liverpool  :***************************** 8690208.43 $
    Leeds      :***************************** 8669855.04 $
    Nottingham :***************************** 8650692.99 $
    Edinburgh  :***************************** 8556538.61 $
            

Часове с най-голяма сума продажби (top 5)
---------------------------------
    2015-12-01 17:00:00+00:00 :****************************** 495425.73 $
    2016-01-02 11:00:00+00:00 :***************************** 486492.2 $
    2016-01-04 18:00:00+00:00 :***************************** 486254.26 $
    2016-01-07 10:00:00+00:00 :***************************** 480126.26 $
    2015-12-22 13:00:00+00:00 :***************************** 479260.66 $

С времето така и не успях да махна секундите и часовата зона. Опитах с отелни условия и разни cast-вания, но чесно казано вече съм изпушил и изобщо не ми се занивама. Драгите потребители ще си гледат часовата зона :D 

Edit: Поиграх си още 20 минути и си копирах кода от програмата в друга версия, този път - един файл, използващ само функции. По този начин намалих времето за което програмата работи на приблизително 1мин:10сек - 1мин:20сек. Явно обектите ми не струват, тъй като използвам много цикли ( общо пет пъти минавам през целия файл ) и следователно на процесорчето му отнема време. При функциите използвам само един цикъл и записвам всички данни едновременно. 

Просто малко интересна информация ( може би! )

Интересно ми е как са се представили други хора, така че пишете с резултати и тестове. Особено ми е интересно ако някой е завършил програмата, която Борис пише в лекциите. Дали може програма с обекти да се справи по-бързо от моята с функции. 

 

Тагове:
0
Python 03/02/2016 01:51:08
ttitto avatar ttitto 1153 Точки

Моето решение също е с ООП, но изциклям само веднъж по продажбите. Или по-точно веднъж ги минава самия рийдър, за да се създадат обектите и втори път ги минават анализаторите. Ползвал съм Strategy шаблон - за всеки анализ си имам клас, който има собствена имплементация на два метода. Единият метод обработва единична продажба според своите нужди, а вторият метод принтира анализираните резултати. Така в клиента се налага само да направя списък от анализатори. След това за всяка продажба и за всеки анализатор да мина и да извикам на анализатора първия метод и накрая само да мина през анализаторите и да им кажа да се отпечатат.

Не съм замервал скорости и кодът още не е съвсем довършен, защото като го писах таковата не работеше и условията не ми бяха съвсем ясни в подробности, но се надявам тази вечер да го довърша и ще сложа линк тук.

1
achobanov avatar achobanov -4 Точки

Това е интересен подход, със сигурност е доста по-чисто от това, което аз съм направил. Макар, че ако правилно съм те разбрал запазваш данните от всеки анализ в отделен лист. Което означава, че накрая на задачата, когато опре да ги обработваш - пак трябва да итерираш доста листове, което също ще отнеме време. Поне така ми се струва, може и да бъркам. Ще ми бъде интересно да я прегледам като я довършиш ( можеш да ме улесниш с някой друг #коментар :Д)

0
ttitto avatar ttitto 1153 Точки

Не пазя всеки анализ в отделен списък, а в отделен обект. В смисъл всеки анализатор си знае какво трябва да прави и съответно си пази каквото му трябва, като още при итерацията на продажбите си подрежда данните: ето това е частта от клиента, която ще ти помогне да ме разбереш, че сега не мога да отделя много време да кача кода

 all_analyzers = []
    common_analyzer = CommonAnalyzer()
    by_category_analyzer = SalesByCategoryAnalyzer( items)
    by_town_analyzer = SalesByTownAnalyzer()
    by_utc_hour_analyzer = SalesByUtcHoursAnalyzer()

    all_analyzers.append(common_analyzer)
    all_analyzers.append(by_category_analyzer)
    all_analyzers.append(by_town_analyzer)
    all_analyzers.append(by_utc_hour_analyzer)

    for s in sales:
        for an in all_analyzers:
            an.handle_sale(s)

    for an in all_analyzers:
        an.analyze()

0
ttitto avatar ttitto 1153 Точки

Ето го и решението ми, както обещах по-горе. При мен най-големия файл минава за 50 сек.

Между другото, achobanov, сравних моите резултати с твоите и има разлика при сортирането по категории. Ти сортираш по подкатегории, а аз по категории.

0
RoYaL avatar RoYaL Trainer 6849 Точки

Подозирам, че ако ползвате генератори, докато пълните списъците с обекти ще е още по-бързо

В смисъл такъв:

1. Четеш ред от файла

2. Създаваш обект със стойностите от този ред

3. yield-ваш обекта

После форийча върху метода, който създава обектите няма да изцикли втори път списък с обекти, които преди това са били създадени изцикляйки 100К реда файл.

След това тези обекти могат да бъдат вкарани в множество речници паралелно - едновременно в речник по категория, по град и по дата.

Притеснява ме, че тези речници после трябва да се сортират. Не знам дали сте го преборили този проблем. Аз това, което се сещам от към бързодействие е да се сортира колекцията по време на добавяне. Но и това си идва със своите trade-off-ове. http://stackoverflow.com/questions/5527630/is-there-a-standard-python-data-structure-that-keeps-thing-in-sorted-order

Някой, ако му се пробва може да види дали е по-бързо да се използва това, от колкото сортиране на речника след като е напълнен.

0
achobanov avatar achobanov -4 Точки

Още не съм гледал лекцията с генератори, така че нямам представа. 

0
RoYaL avatar RoYaL Trainer 6849 Точки

Long story short с генератори/итератори/енумератори (може би си ги чувал така в C#/Java) можеш да добавиш форийч функционалност :-) На всяко извикване на форийча се "изплюва" по една стойност. В C# това става с yield return. В python с yield.

0
supersane avatar supersane 234 Точки

Моят ООП начин на тази задача беше следния: Имам клас Item, който създава обект на база на прочетения ред от catalog файла, с пропъртита информацията дадена в каталога. Имам клас Catalog, който има "вътрешна" функция, която прочита каталога и го разхвърля в речник, който речник е пропърти. За ключ речника държи ID на продукта, а за стойност създадения обект от тип Item. И трети клас Sales, който отново с "вътрешна" функция чете подадения файл и го запазва в пропърти. След като при създаването на обект от тип Sales и Catalog, вече те държат в себе си заредената информация(предполагам изобщо не е добра идея от гледна точка, че така ще се държи всичко и ще яде памет, ама ето пък има причина за оптимизация :) ). Анализите вече съм ги направил, като методи част от класовете Sales и Catalog. Пуснах файла с 1M и на мен ми отне около минутка и няколко секунди, за обработката, и аз също съм с intel i5 двуядрен, сравнително старичък мисля.

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.