0

I am looking to retrieve the Machine VM id which has the latest creation datetimestamp value,

Below is the code but it returns incorrect value m3.

def get_machine_id_latest_datetimestamp(self):
    thisdict = {
        "machines-xyz-123": {
            "vm": {
                "id": "m1",
                "createTimestamp": "2020-11-27T09:44:02.272908941Z",
                "status": "running"
            }
        },

        "machines-abc-567": {
            "vm": {
                "id": "m2",
                "createTimestamp": "2020-11-27T23:15:22.212021105Z",
                "status": "running"
            }
        },

        "machines-vvy-569": {
            "vm": {
                "id": "m3",
                "createTimestamp": "2020-11-27T22:18:00.572021105Z",
                "status": "running"
            }
        },

        "machines-tgh-m4": {
            "vm": {
                "id": "m4",
                "createTimestamp": "2020-11-27T14:01:22.412621105Z",
                "status": "running"
            }
        }
    }


    machine_id_timestamp_dictionary = {}
    machines_count = len(thisdict)
    machine = list(thisdict.keys())

    for i in range (machines_count):
        machine_id = thisdict[machine[i]]["vm"]["id"]
        vw_creation_timestamp = \
            thisdict[machine[i]]['vm']['createTimestamp']
        machine_id_timestamp_dictionary[machine_id] = vw_creation_timestamp

    latest_created_machine_id = 0
    machine_filtered = set()

    for machine_id in machine_id_timestamp_dictionary:
        if machine_id_timestamp_dictionary[machine_id] > thisdict[machine[i]]['vm']['createTimestamp']:
            latest_created_machine_id = machine_id
            machine_filtered.add(latest_created_machine_id)
    print("Latest Created Machine ID")
    print(latest_created_machine_id)

Ideally the Machine ID m2 should be returned as it is the latest created id, Any pointers why the code is failing?

martineau
  • 119,623
  • 25
  • 170
  • 301
Automation Engr
  • 444
  • 2
  • 4
  • 26

2 Answers2

1

Below. The idea is to scan the dict values, convert each date string into datetime and find the maximum.

from datetime import datetime

d = {
    "machines-xyz-123": {
        "vm": {
            "id": "m1",
            "createTimestamp": "2020-11-27T09:44:02.272908941Z",
            "status": "running"
        }
    },

    "machines-abc-567": {
        "vm": {
            "id": "m2",
            "createTimestamp": "2020-11-27T23:15:22.212021105Z",
            "status": "running"
        }
    },

    "machines-vvy-569": {
        "vm": {
            "id": "m3",
            "createTimestamp": "2020-11-27T22:18:00.572021105Z",
            "status": "running"
        }
    },

    "machines-tgh-m4": {
        "vm": {
            "id": "m4",
            "createTimestamp": "2020-11-27T14:01:22.412621105Z",
            "status": "running"
        }
    }
}


def _as_dt(x):
    return datetime.strptime(x[:19], '%Y-%m-%dT%H:%M:%S')


values = list(d.values())
latest = values[0]['vm']['id']
latest_date = _as_dt(values[0]['vm']['createTimestamp'])
for i in range(1, len(values)):
    dt = _as_dt(values[i]['vm']['createTimestamp'])
    if dt > latest_date:
        latest_date = dt
        latest = values[i]['vm']['id']
print(f'Latest vm: {latest}')

output

Latest vm: m2
balderman
  • 22,927
  • 7
  • 34
  • 52
  • That works. Could you also point the issue in my original code ... if possible? – Automation Engr Nov 29 '20 at 15:59
  • Sure. You did not convert the time stamps into date object. You compared strings. – balderman Nov 29 '20 at 16:04
  • @balderman: string comparison works just fine (see my answer); there must be another mistake in the OP's code. – FObersteiner Nov 29 '20 at 16:35
  • @MrFuppes this may be a corner case where the date string is an iso date. In general you would like to convert the date string into date object. – balderman Nov 29 '20 at 16:49
  • @MrFuppes Can you please re-post your answer having the string comparison? would like to try it out and compare it with my original code to debug the issue. – Automation Engr Nov 29 '20 at 18:19
  • @AutomationEngr: sure. I agree that *in general*, you should consider conversion of string to datetime. You could integrate that in `sorted` by `key` as well, see also https://stackoverflow.com/a/62769371/10197418 – FObersteiner Nov 29 '20 at 21:10
1

Since you have ISO format timestamps, you can sort on string (skipping the conversion to datetime is more efficient). Set reverse=True and just pick the first element:

# assuming 'd' holds your nested dicts:
sortedDicts = sorted(d.values(), key=lambda d: d['vm']['createTimestamp'], reverse=True)

newestVmId = sortedDicts[0]['vm']['id']

print(newestVmId)
# m2
FObersteiner
  • 22,500
  • 8
  • 42
  • 72