Home > Blockchain >  Why is item not adding to dictionary in Python
Why is item not adding to dictionary in Python

Time:02-11

This code

def process_hero_box_annotations(post_to_boxes):
  for box in post_to_boxes:
    k = box
    a = post_to_boxes.get(box)
    new = ()
    post_to_processed_box = {}
    if len(a) != 0:
      x0 = a[0][0]
      y0 = a[0][1]
      x1 = a[0][2]
      y1 = a[0][3]
      if len(a) == 2:
        if a[0][0] < a[1][0]:
          x0 = a[0][0]
        else:
          x0 = a[1][0]
        if a[0][1] < a[1][1]:
          y0 = a[0][1]
        else:
          y0 = a[1][1]
        if a[0][2] > a[1][2]:
          x1 = a[0][2]
        else:
          x1 = a[1][2]
        if a[0][3] > a[1][3]:
          y1 = a[0][3]
        else:
          y1 = a[1][3]
      new = (x0, y0, x1, y1)
      print(new)
      post_to_processed_box[k] = new
  return post_to_processed_box

gives me

{
    384121: (10, 20, 100, 300)
}

when I want

{
    149321: (14, 10, 503, 545),
    384121: (10, 20, 100, 300)
}

Why is one item not adding?

CodePudding user response:

Move the following statement @ line 6 outside of the loop
post_to_processed_box = {}

So it would look more similar to the following

def process_hero_box_annotations(post_to_boxes):
  post_to_processed_box = {}
  for box in post_to_boxes:
    k = box
    a = post_to_boxes.get(box)
    new = ()
    if len(a) != 0:
      x0 = a[0][0]
      y0 = a[0][1]
      x1 = a[0][2]
      y1 = a[0][3]
      if len(a) == 2:
        if a[0][0] < a[1][0]:
          x0 = a[0][0]
        else:
          x0 = a[1][0]
        if a[0][1] < a[1][1]:
          y0 = a[0][1]
        else:
          y0 = a[1][1]
        if a[0][2] > a[1][2]:
          x1 = a[0][2]
        else:
          x1 = a[1][2]
        if a[0][3] > a[1][3]:
          y1 = a[0][3]
        else:
          y1 = a[1][3]
      new = (x0, y0, x1, y1)
      print(new)
      post_to_processed_box[k] = new
  return post_to_processed_box

with your current code you are setting post_to_processed_box to an empty dictionary each iteration of the loop.

CodePudding user response:

@Jadon's answer definitely solves your problem.

I want to offer this as another way of thinking of the problem of getting a "hero box" (a union of two rectangles):

  • It uses some different logic, which I think might be easier to follow as it avoids nested if-blocks.
  • I chose to use the min() and max() functions to find the minimums and maximums for X and Y.
  • I'm also using the items() method on the dict of boxes passed in, to get both the key and value/object in one statement.
import pprint


def union(box_a, box_b):
    '''Return a box that both minimally & fully covers box_a and box_b.
    A box is a 4-part tuple: (minX, minY, maxX, maxY)
    '''

    min_x = min(box_a[0], box_b[0])
    min_y = min(box_a[1], box_b[1])
    max_x = max(box_a[2], box_b[2])
    max_y = max(box_a[3], box_b[3])

    return (min_x, min_y, max_x, max_y)


def process_hero_box_annotations(post_to_boxes):
    post_to_processed_box = {}

    for key, boxes in post_to_boxes.items():

        if len(boxes) > 2:
            raise ValueError(f'Expected 0, 1, or 2 boxes, got {len(boxes)} boxes')

        if len(boxes) == 0:
            post_to_processed_box[key] = ()
            continue  # move on to the next set of key/boxes, if there is one

        box_a = boxes[0]
        hero_box = (box_a[0], box_a[1], box_a[2], box_a[3])

        if len(boxes) == 2:
            box_b = boxes[1]
            hero_box = union(box_a, box_b)

        post_to_processed_box[key] = hero_box

    return post_to_processed_box

I mocked up some input that should produce the expected output you shared:

boxes = {
    149321: [(14, 10, 500, 500), (20, 20, 503, 545)],
    384121: [(10, 20, 100, 300), (50, 50, 90, 250)]
}

When I run it , I get your expected result:

hero_boxes = process_hero_box_annotations(boxes)

expected = {
    149321: (14, 10, 503, 545),
    384121: (10, 20, 100, 300)
}

assert hero_boxes == expected

pprint.pprint(hero_boxes, width=30)
{149321: (14, 10, 503, 545),
 384121: (10, 20, 100, 300)}
  • Related