What is the total amount within a specified date range when retrieved as JSON?

Consider the following JSON structure:

{
    "timesheets": [
        {
            "user": {
                "username": "erik",
                "first_name": "Erik",
            },
            "project_id": 4,
            "calc_full_week": {
                "2020-06-22": 5,
                "2020-06-23": 10,
                "2020-06-24": 8,
                "2020-06-25": 13,
                "2020-06-26": null,
                "2020-06-27": null,
                "2020-06-28": null
            }
        },
        {
            "user": {
                "username": "erik",
                "first_name": "Erik",
            },
            "project_id": 4,
            "calc_full_week": {
                "2020-06-29": 15,
                "2020-06-30": 10,
                "2020-07-01": null,
                "2020-07-02": null,
                "2020-07-03": null,
                "2020-07-04": null,
                "2020-07-05": null
            }
        },
        {
            "user": {
                "username": "rawwe",
                "first_name": "joey",
            },
            "project_id": 4,
            "calc_full_week": {
                "2020-06-22": 3,
                "2020-06-23": 10.4,
                "2020-06-24": 8,
                "2020-06-25": 8,
                "2020-06-26": 8,
                "2020-06-27": 8,
                "2020-06-28": 5
            }
        }
    ]
}

I am seeking an efficient way to extract the sum of values from calc_full_week within a specified range. For example, if I provide the range 2020-06-25 - 2020-07-03, the total sum of values within that range should be calculated (13+15+10+8+8+8+5 for the given JSON).

Now, the dilemma is whether to perform these calculations on the backend (django) or using JavaScript on the client side.

In my Django model, the structure is as shown below:


class Timesheet(Model):
    year = PositiveIntegerField(validators=[MaxValueValidator(2500), MinValueValidator(1900)])
    week = PositiveIntegerField()
    project = ForeignKey("projects.Project", on_delete=CASCADE)
    user = ForeignKey("accounts.User", on_delete=CASCADE)
    day_1 = DecimalField("monday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_2 = DecimalField("tuesday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_3 = DecimalField("wednesday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_4 = DecimalField("thursday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_5 = DecimalField("friday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_6 = DecimalField("saturday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_7 = DecimalField("sunday", blank=True, null=True, max_digits=4, decimal_places=1)

I serialize this data and include a

 calc_full_week = serializers.SerializerMethodField()
attribute, with the calculation logic detailed in the method below:

 def get_calc_full_week(self, obj):
        current_week = obj.week
        current_year = obj.year
        # Since week 1 corresponds to week 0
        week = current_week - 1
        # List containing each date of a given week
        startdate = time.asctime(time.strptime('%d %d 1' % (current_year, week), '%Y %W %w'))
        startdate = datetime.datetime.strptime(startdate, '%a %b %d %H:%M:%S %Y')

        date_dict = {}
        days_in_week = [obj.day_1, obj.day_2, obj.day_3, obj.day_4, obj.day_5, obj.day_6, obj.day_7]
        for i in range(0, 7):
            day = startdate + datetime.timedelta(days=i)
            date_dict[day.strftime('%Y-%m-%d')] = days_in_week[i]

        return date_dict

Answer №1

const data = {
    "statistics": [
        {
            "user": {
                "username": "erik",
                "first_name": "Erik",
            },
            "project_id": 4,
            "weekly_hours": {
                "2020-06-22": 5,
                "2020-06-23": 10,
                "2020-06-24": 8,
                "2020-06-25": 13,
                "2020-06-26": null,
                "2020-06-27": null,
                "2020-06-28": null
            }
        },
        {
            "user": {
                "username": "erik",
                "first_name": "Erik",
            },
            "project_id": 4,
            "weekly_hours": {
                "2020-06-29": 15,
                "2020-06-30": 10,
                "2020-07-01": null,
                "2020-07-02": null,
                "2020-07-03": null,
                "2020-07-04": null,
                "2020-07-05": null
            }
        },
        {
            "user": {
                "username": "rawwe",
                "first_name": "joey",
            },
            "project_id": 4,
            "weekly_hours": {
                "2020-06-22": 3,
                "2020-06-23": 10.4,
                "2020-06-24": 8,
                "2020-06-25": 8,
                "2020-06-26": 8,
                "2020-06-27": 8,
                "2020-06-28": 5
            }
        }
    ]
}

const calculateTotalHours = (startDate, endDate) => {
  const startRange = +startDate.split('-').join('')
  const endRange = +endDate.split('-').join('')
  let totalHours = 0
  data.statistics.reduce((acc, val) => {
    Object.keys(val.weekly_hours).map((date, index) => {
      const dateSplit = +date.split('-').join('')
      if (dateSplit >= startRange && dateSplit <= endRange) {
        totalHours += val.weekly_hours[date]
      }
    })
  }, 0)
  return totalHours
}

console.log(calculateTotalHours('2020-06-25', '2020-07-03'))

Answer №2

If you're interested in achieving this task using Python, consider the following approach:

Start by creating a list of allowed dates:

my_date_range = ['2020-06-25', '2020-06-26', ]

It would be beneficial to have a separate method that generates this list based on a specified start and end date, like the one suggested in this Stack Overflow answer.

To simplify the extraction of required sub-nodes from nested dictionaries or JSON objects, you can leverage a library like dpath:

import json
import dpath

data = json.loads(json_string)  # convert JSON string to dictionary format

# filter the dictionary for all date values within a certain range
# utilizing wildcard (*) for flexibility in key name filtering
# setting yielded=True returns a generator for tuples instead of a dictionary
result = dpath.util.search(data, "timesheets/*/calc_full_week/2020-*", yielded=True)

# Calculate the sum of the required dates while filtering out None values
my_sum = sum(filter(None, [v for k, v in result if k in my_date_range]))

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

React Native encountered an error: `undefined` is not an object

Encountering the commonly known error message "undefined is not an object" when attempting to call this.refs in the navigationOptions context. Let me clarify with some code: static navigationOptions = ({ navigation, screenProps }) => ({ heade ...

Utilizing Node.js, delete the author from the database and then use a GET request to display all

Exploring node and express for the first time. I've been working on an example that utilizes GET and POST methods, but now I want to implement DELETE function to delete a book based on its title. Additionally, I need to introduce another GET method to ...

How can we identify if the user is utilizing a text-input control?

Incorporating keyboard shortcuts into my HTML + GWT application is a goal of mine, but I am hesitant about triggering actions when users are typing in a text area or utilizing the keyboard for select menu operations. I am curious if there exists a method ...

Utilize Jquery to locate and update the text of all div elements that have an empty id attribute

I need help with a task involving a list of divs, some with ids and some without. My goal is to identify all the divs within a specific class that have empty ids and change their inner text to say "no data available". Can this be done? My attempt using $( ...

The search feature in AngularJS with filter appears to be malfunctioning

I've been attempting to use the angularjs filter method for searching, but it doesn't seem to be working correctly. Despite not seeing any errors in the console, the search results aren't showing up. Can someone lend a hand with this? Below ...

Having trouble running nodemon on my Windows 10 machine

Recently, I started diving into Node.js and managed to run my first node app successfully, albeit without using nodemon. To remedy this, I globally installed nodemon by running npm install -g nodemon, which went smoothly. However, upon executing nodemon in ...

Attempting to extract the text within a table row cell by clicking on the cell directly following it

I am trying to extract the data from a table row when I click on a specific div within that row HTML: <td class="ms-cellstyle ms-vb2">10</td> <td class="ms-cellstyle ms-vb2"> <div class="ms-chkmark-container"> <div ...

Guide on verifying the presence of an alert with nodejs webdriver (wd)

I am currently facing a challenge when writing a test where I need to verify the existence of an alert, check its text if it is present, and then accept it. Although I have researched on platforms like Stack Overflow for solutions such as checking for ale ...

Retrieve the data stored in a JSON object

After making an ajax call, the json object that gets returned looks like this: Object {0: "1", 1: "jake", 2: "#00ff00", tip_id: "1", tip_details: "jake", tip_color: "#00ff00"} Object {0: "2", 1: "jakee", 2: "#00ff00", tip_id: "2", tip_details: "jakee", t ...

Transforming a value within a controller into a directive

I am uncertain if I am approaching this correctly, but my goal is to convert a piece of code from a controller to a directive. The reason for this change is that I want to reuse the code with different values without creating multiple large object literals ...

The server cannot be started by Npm, the complete log is available. However, this project has the ability to operate on a different computer

I am facing an issue with a Vue NodeJs project that I copied from another computer. While it runs smoothly on the original computer, I am encountering difficulties running it on this one. Although I have installed Node.js here, the project fails to run as ...

Toggle the sidebars to slide out and expand the content division using JavaScript

I am looking to achieve a smooth sliding out effect for my sidebars while expanding the width of the middle content div. I want this action to be toggled back to its original state with another click. Here's what I've attempted so far: $(' ...

Issues with Collision Detection between Canvas Rectangles and Balls

I am developing an HTML5 canvas game and encountering an issue with collision detection. The problem occurs when the ball collides with any platform - the ball's gravity should change to -1 and move upwards at the same velocity as the platforms. Howev ...

The Jquery append() method seems to be having issues specifically in the Internet Explorer

I am a jQuery 1.10.2 version with the task of inserting an XML node at a specific location within an existing XML structure. To achieve this, I am utilizing the jQuery `append()` function successfully in Chrome, Firefox, and IE Edge; however, it is encount ...

How to customize the background of radio buttons in HTML

I want the background color to stay consistent as lightgray for each <ul>. Currently, clicking the radio button causes the ul's background to change incorrectly. I am unsure of how to loop through all available ul elements using jQuery and woul ...

What is the jQuery syntax for targeting a specific element within an object?

Is there a way to access a sub element from $(this)? For instance, how can I specifically select a span element inside the this object? ...

The browser is not showing JavaScript alerts and prompts when they are called inside a function

/*I am attempting to run a color guessing game in my browser, but when I try opening the code in Chrome, it doesn't work. Any suggestions or ideas would be greatly appreciated.*/ var colors = ["Aqua", "Black", "Blue", "Brown", "Coral", " ...

Looping through multi-dimensional JSON objects with jQuery

Hello there, I'm currently facing some challenges in getting the screen below to work properly: Project progress screen I have generated the following JSON data from PHP and MYSQL. My goal is to display the project alongside user images and names whe ...

Generating a primary XML element encompassing multiple namespaces

I am currently working on integrating Restful services with Backbone.js framework. In this project, I need to send XML data and add multiple namespaces to it. Here is the snippet of my current JavaScript code: var mainNamespace = "xmlns='http://serv ...

Prevent the countdown timer from resetting every time I refresh the page

Whenever I refresh my page, the timer starts over. I want it to pick up from where it left off until it reaches 0. This is my JavaScript code for handling the timer: var target_date = new Date().getTime() + (1000*3600*48); // set the countdown date var ...