Професионална програма
Loading...
ognyan.tod avatar ognyan.tod 0 Точки

Относно задачата: Намерете времето с най-големи продажби

http://python3.softuni.bg/student/lecture/assignment/569e362f6e8efb1652742e99/

 

Някой, дали ще може да напише решение на задачата, че не ми е много ясно как точно да я направя.
Също ще съм доволен и на напътствия :)

Тагове:
0
Python
RoYaL avatar RoYaL Trainer 6847 Точки

Задачката много прилича на ръчна имплементация на индексация в база данни :) Когато индексираш колона в база данни, де факто създаваш вътрешна структура от данни, която има бързо търсене по стойност в колоната, което можем да си го представим като хаштаблица (речник), където стойността е ключ в речника. (Изключаем фултекст индексите, където работата е много по-дебела).

Като имаме тази предистория предвид, знаем че това, което искаме да направим е стойността, по която търсим/групираме да я направим като ключ в речник. В първата част от задачата това са дните от седмицата. Колегата по-горе е представил една възможност - да се вкара целия Date обект. Не съм сигурен, че разбрах обяснението му на сто процента, но подозирам, че така щампата ще е закръглена до дата (23,24,25,26...), а не до ден от седмицата (1,2,3,4...7). Върху дейт обекта можеш да извикаш weekday() и ще ти върне число от 0 до 6. 0 е понеделник, а 6 е неделя.

Можеш да използваш тях като ключове.

Тук за целта на задачата искаме да изкараме деня с най-много продажби. За щастие след като са дни от седмицата, не е голям проблем да въртим по речника за да намерим този с най-голяа стойност, тъй като ще завъртим само 7 пъти в най-лошия случай. Това може да се сведе и до по-малко операции, ако проверяваме на момента, в който добавяме продажби за някой ден, те не са станали повече от текущия максимум.

Разбира се тук проверките стават повече, от колкото ако после проверим речника, така че трябва да се съобразим с това къде имаме повече операции. Дали ако на всяко сканиране на ред направим 3 операции или ако после изсканираме резултатната таблица наново. В конкретния случай може би е по-добре както е споменал колегата по-горе - да претърсим речника накрая.

1
ognyan.tod avatar ognyan.tod 0 Точки

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

from datetime import datetime


FILE = './sales.csv'
dateformat = '%Y-%m-%d %H:%M:%S'

with open(FILE, 'r') as file:
    line = [ line.strip().split(',') for line in file]
    values = {
        'Monday': 0,
        'Tuesday': 0,
        'Wednesday': 0,
        'Thursday': 0,
        'Friday': 0,
        'Saturday': 0,
        'Sunday': 0
    }

    for i in line:
        date = datetime.strptime(i[0], dateformat)
        weekday = date.strftime('%A')
        if weekday == 'Monday':
            values['Monday'] = values['Monday'] + float(i[1])
        elif weekday == 'Tuesday':
            values['Tuesday'] = values['Tuesday'] + float(i[1])
        elif weekday == 'Wednesday':
            values['Wednesday'] = values['Wednesday'] + float(i[1])
        elif weekday == 'Thursday':
            values['Thursday'] = values['Thursday'] + float(i[1])
        elif weekday == 'Friday':
            values['Friday'] = values['Friday'] + float(i[1])
        elif weekday == 'Saturday':
            values['Saturday'] = values['Saturday'] + float(i[1])
        elif weekday == 'Sunday':
            values['Sunday'] = values['Sunday'] + float(i[1])
    print('{} = {:.2f}'.format('Monday', values['Monday']))
    print('{} = {:.2f}'.format('Tuesday', values['Tuesday']))
    print('{} = {:.2f}'.format('Wednesday', values['Wednesday']))
    print('{} = {:.2f}'.format('Thursday', values['Thursday']))
    print('{} = {:.2f}'.format('Friday', values['Friday']))
    print('{} = {:.2f}'.format('Saturday', values['Saturday']))
    print('{} = {:.2f}'.format('Sunday', values['Sunday']))

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

    for i in line:
        date = datetime.strptime(i[0], dateformat)
        weekday = date.strftime('%A')
        for key in values:
            # print(key)
            if weekday == key:
                values[key] = values[key] + float(i[1])
    
    print('{} = {:.2f}'.format(weekday, values[key]))

 

Интересува ме също така конвертирането на стринг в datetime.
В този случай във файла датата ми изглежда така - 2015-11-24 04:07:00
и конвертирането и в datetime го правя така:
 

date_string = '2015-11-24 04:07:00'
date = datetime.strptime(i[0], '%Y-%m-%d %H:%M:%S')
weekday = date.strftime('%A')

Въпроса ми е задължително ли е да парсвам целият стринг с (%Y-%m-%d %H:%M:%S) или мога по някакъв начин без да парсвам да го накарам да взима само частта с датата? Понеже ако във файла имам друг формат на дата, например 2015/11/24) ще ми се счупи кода.

0
RoYaL avatar RoYaL Trainer 6847 Точки

Ключовете в един речник са сет от стойности. Речникът като обект има предефиниран оператор "in" чрез магическия __contains__() метод, който със сложност O(1) намира дали даден ключ съществува.

Можеш да търсиш за наличие на ключ без да итерираш из ключовете (бавна операция), а използвайки "in".

if weekday in values:

    values[weekday] += float(i[1])

Можеш да изпринтиш и всички ключ стойности с цикъл, вместо ръчно 1 по 1:

for key, value in values.items():

    print('{} = {:.2f}'.format(key, value))

1
ognyan.tod avatar ognyan.tod 0 Точки

Благодаря много за помоща.

Би ли ми отговорил и на вторият въпрос, който е свързан с датите?

0
RoYaL avatar RoYaL Trainer 6847 Точки

Ако ще подаваш стринг, който включва и време, ще трябва да парснеш и времето. После можеш да го зарежеш, ако искаш, по кой да е от начините. Не подава времевия стринг. Разцепи датата по спейс и вземи само нулевата част, например.

0