Package: data-struct
data-structstructLib is essentially a module which contains theStructclass. This class specifically
aims at making your life easier when working with JSON-like objects (meaning nesteddict/listobjects)InstallationTo install structLib on your python setup, run the following:pipinstalldata-structOn linux or mac you will probably need to run this command instead:python3-mpipinstalldata-structPlease note that version 3.8 (or higher) of python is required to run this library!UsageLet's have closer look at what we can do with this library and how...
If you take a look at the code or the help module you will notice that theStructclass isn't the only element in there.
There is indeed a bunch of other functions defined. The only reason these functions are not part of the class is because
they work using recursive algorithms, therefore it was way easier to implement them outside and then simply call them from
the class methods when needed. Note that youshould notbe using those functions, theStructclass handles all of that for you.ExampleNow let's look at some code shall we? The following code can be found in the examples folder.# This code aims to illustrate how we can use structLibfromstructLibimportStruct# You will notice I only import the Struct class, the reason in because it's the only thing actually useful for# uswithopen("actors.json")asf_in:data=Struct.load(f_in)# First we load the data into a Struct object.print(data,'\n')"""Let's say I want to see if "Tom Cruise" is present in the data structureI could use the Struct.isValueIn() method but if I want to know where the value is, there is a better option"""path=data.pathToValue("Tom Cruise")# If the value doesn't exist in the Struct, the result will be Noneprint(path)# Now I want to get his age:age=data["Actors",0,'age']print(age,'\n')# The value is wrong let's fix thatdata["Actors",0,"age"]=58# Let's add Jonny Depp in therejonny={"name":"Jonny Depp","age":57,"Born At":"Owensboro, Kentucky","Birthdate":"June 9, 1963","photo":"https://upload.wikimedia.org/wikipedia/commons/thumb/7/79/Johnny_Depp_Deauville_2019.jpg/390px""-Johnny_Depp_Deauville_2019.jpg",}data['Actors'].append(jonny)print(data,'\n')# Let's say I want to print the ages of everyone:foraindata.getAll("age"):print(a)# Now let's sort them by agedata['Actors']=Struct(data['Actors']).sorted(path="age").data# Here I have to do this complicated mess because the list isn't at the top level of the structure but rather# under the "Actors" keyprint(data)# Finally let's write that back into the filewithopen("sorted_actors.json",'w')asf_out:data.dump(f_out,indent=4)The constructorCreating aStructinstance couldn't be easier:fromstructLibimportStructs=Struct(data)In most cases,datawould be a list or a dictionary. But even if it's not the case, the object will automatically be deserialized
by putting all its attributes into a dict object. That being said, keep in mind that any non-builtin type will be converted to a string so
make sure that all the data contained in your object is indeed convertible into a string, otherwise some information will be lost.Iterating through a StructTheforsyntax works perfectly withStructobjects but the behavior depends on what type of data we have. Ifself.datais a list,for element in struct_objectwill work exact way as for a regular list object, no mystery there.However ifself.datais a dictionary, thenelementwill be a tuple containing the key, and the corresponding value.The sorted/sort methodsThose are interesting. The only difference between the two is that thesortmethod modifies the object directly and returns nothing, while thesortedmethod
returns the sorted version of the object but leaves the original as is. Aside from that the behavior is exactly the same. With that out of the way, let's look at the
interesting in partUsage:struct_object.sort(path=None,function=lambdax:x)Thepathargument specifies which value should be prioritized to run the sort.Thefunctionis a function that will be executed on the value. The default islambda x:x, which is a function that does explicitly nothing to the value it receives.The behavior of the sort will depend on what type of data you have. Indeed, theself.dataattribute can either be alistor adictobject.We then have four possible situations:If it's a list andpathisNone, the list will be sorted directly based on the values it contains.If it's a list andpathis specified, the list will be sorted based on the value which corresponds topathin each element on the list.If it's a dict andpathisNone, the dict will be sorted based on thekeys.If it's a dict andpathis specified, the dict will be sorted based on the value corresponding to the path in each element of the dict.Let's give an example:fromstructLibimportStructfromdatetimeimportdatetimedefparseDate(string):content=[int(x)forxinstring.split('-')]returndatetime(year=content[2],month=content[1],day=content[0])data=Struct({"10-08-2020":{'id':2},"7-08-2020":{'id':1},"1-07-2020":{'id':3}})deftest1():# Sort by datedata.sort(function=parseDate)assertdata.getAll("id")==[3,1,2]deftest2():# Sort by iddata.sort('id')assertdata.getAll("id")==[1,2,3]# now if it's a listdata2=Struct([1,8,3])deftest3():# Note that using Struct for a simple list like this is pointlessassert[xforxindata2.sorted()]==[1,3,8]data3=Struct([{"date":"10-08-2020"},{"date":"7-08-2020"},{"date":"1-07-2020"}])deftest4():data3.sort("date",parseDate)assert[x["date"]forxindata3]==["1-07-2020","7-08-2020","10-08-2020"]RequirementsNone! That's also what is cool about it!AuthorsEddieBreeg