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

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

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

 

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

Тагове:
0
Python
orelcho avatar orelcho 2 Точки

Аз съм го направил така:

За всяка дата от файла съм използвал метода на datetime.replace.
За 1-вата част на задачата replace-вам часове, минути, секунди и микросекунди с 0. Така получената времева щампа е "закръглена" до ден и я използвам за ключ в речник. Когато обработвам един ред, ако текущата времева щампа съществува като ключ към стойността ѝ добавям текущата цена. Накрая претърсвам речника за ключа с най-голяма стойност
За 2-рата част от задачата replace-вам всичко без часовете и пак същата логика

Пробвай да измислиш кода сам

0
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