Associating unique logging-calls to an id across runs - python

I need to be able to associate a log to an id that stays persistent across runs e.g:
logging.log("Hello") # 1
logging.log("World") # 2
Obviously this only works as long as you don't modify the code
logging.log("Hello") # 1
logging.log("beautiful") # 2
logging.log("World") # 3 <--- ID should be 2 here!!
The solution would seem simple... just create a hash over the log message and you're good to go right?
Sadly, I have to consider following possibility:
logging.log("Hello")
logging.log("World")
...
logging.log("World") # This would assign to the same hash/id as the previous log to 'World'
The only ideas i've come up with to tackle this problem are:
Running static analysis or a diff on the code beforehand and analyzing it
Are there any tools suitable for the job?
Can they be implemented realistically?
Making the user manage the IDs (not very user friendly)
logging.log("10", "Hello")
logging.log("20", "World")
Or is there another solution I'm not seeing?

Related

Struggling with how to iterate data

I am learning Python3 and I have a fairly simple task to complete but I am struggling how to glue it all together. I need to query an API and return the full list of applications which I can do and I store this and need to use it again to gather more data for each application from a different API call.
applistfull = requests.get(url,authmethod)
if applistfull.ok:
data = applistfull.json()
for app in data["_embedded"]["applications"]:
print(app["profile"]["name"],app["guid"])
summaryguid = app["guid"]
else:
print(applistfull.status_code)
I next have I think 'summaryguid' and I need to again query a different API and return a value that could exist many times for each application; in this case the compiler used to build the code.
I can statically call a GUID in the URL and return the correct information but I haven't yet figured out how to get it to do the below for all of the above and build a master list:
summary = requests.get(f"url{summaryguid}moreurl",authmethod)
if summary.ok:
fulldata = summary.json()
for appsummary in fulldata["static-analysis"]["modules"]["module"]:
print(appsummary["compiler"])
I would prefer to not yet have someone just type out the right answer but just drop a few hints and let me continue to work through it logically so I learn how to deal with what I assume is a common issue in the future. My thought right now is I need to move my second if up as part of my initial block and continue the logic in that space but I am stuck with that.
You are on the right track! Here is the hint: the second API request can be nested inside the loop that iterates through the list of applications in the first API call. By doing so, you can get the information you require by making the second API call for each application.
import requests
applistfull = requests.get("url", authmethod)
if applistfull.ok:
data = applistfull.json()
for app in data["_embedded"]["applications"]:
print(app["profile"]["name"],app["guid"])
summaryguid = app["guid"]
summary = requests.get(f"url/{summaryguid}/moreurl", authmethod)
fulldata = summary.json()
for appsummary in fulldata["static-analysis"]["modules"]["module"]:
print(app["profile"]["name"],appsummary["compiler"])
else:
print(applistfull.status_code)

Delete Specific branch with Python-Gitlab module

I am extreme beginner in writing python scripts as I am learning it currently.
I am writing a code where I am going to extract the branches which I have which are named something like tobedeleted_branch1 , tobedeleted_branch2 etc with the help of python-gitlab module.
With so much of research and everything, I was able to extract the names of the branch with the script I have given bellow, but now what I want is, I need to delete the branches which are getting printed.
So I had a plan that, I will go ahead and store the print output in a variable and will delete them in a go, but I am still not able to store them in a variable.
Once I store the 'n' number of branches in that variable, I want to delete them.
I went through the documentation but I couldn't figure out how can I make use of it in python script.
Module: https://python-gitlab.readthedocs.io/en/stable/index.html
Delete branch with help of module REF: https://python-gitlab.readthedocs.io/en/stable/gl_objects/branches.html#branches
Any help regarding this is highly appreciated.
import gitlab, os
TOKEN = "MYTOKEN"
GITLAB_HOST = 'MYINSTANCE'
gl = gitlab.Gitlab(GITLAB_HOST, private_token=TOKEN)
# set gitlab group id
group_id = 6
group = gl.groups.get(group_id, lazy=True)
#get all projects
projects = group.projects.list(include_subgroups=True, all=True)
#get all project ids
project_ids = []
for project in projects:
project_ids.append((project.id))
print(project_ids)
for project in project_ids:
project = gl.projects.get(project)
branches = project.branches.list()
for branch in branches:
if "tobedeleted" in branch.attributes['name']:
print(branch.attributes['name'])
Also, I am very sure this is not the clean way to write the script. Can you please drop your suggestions on how to make it better ?
Thanks
Branch objects have a delete method.
for branch in project.branches.list(as_list=False):
if 'tobedeleted' in branch.name:
branch.delete()
You can also delete a branch by name if you know its exact name already:
project.branches.delete('exact-branch-name')
As a side note:
The other thing you'll notice I've done is add the as_list=False argument to .list(). This will make sure that you paginate through all branches. Otherwise, you'll only get the first page (default 20 per page) of branches. The same is true for most list methods.

Linking two fields in 2 different nodes created proceduraly

I am creating a nuke node to easily manipulate my different lights in a node. I want to code it so that it doesn't matter how many lights are in any given file, and the code can figure it out and display the necessary tools to modify them. To achieve this, I first identify how many lights are in the file and store that value, which then gets fed to a 'for' cycle to create as many nodes and tools as lights are on the original file. 'tempNumber' is the number assigned to the original Lights on the file, and it helps create and manage all the tools, labeled to match the light they are modifying. It becomes complicated because the names of the nodes generated look like this:
globals()['expoParent{}'.format(tempNumber)]
Up to now everything has been working fine but I am stuck trying to link two different Exposure nodes to reflect the same values as the user modifies them. I created this code for that purpose on a separate script:
par = nuke.nodes.EXPTool(mode = 'Stops', name = 'Parent')
chi = nuke.nodes.EXPTool(mode = 'Stops', name = 'Child')
par.knob('knobChanged').setValue('chi["red"].setValue(par["red"].value())\nchi["green"].setValue(par["green"].value())\nchi["blue"].setValue(par["blue"].value())')
This previous bit of code works perfectly, it creates 2 Exposure nodes and it links the Child to the Parent so that any change made to the Parent is then automatically passed along to the Child immediately. Now the problem comes when I try to replace the variables par and chi with globals()['expoParent{}'.format(tempNumber)] and globals()['expoChild{}'.format(tempNumber)] . At this point the code stops working and the link is not successful. I have read plenty of people saying that variables should not be created through a for loop but I don't see any other way of doing it.
Why do it with a knobChanged function at all when you can just link the node fields with expressions?
Here's an example that links two grade nodes (Grade1 and Grade2) with Grade1 as the parent. You'll need to have these in your script before running the code. Though you could also create them procedurally.
parent = nuke.toNode('Grade1')
child = nuke.toNode('Grade2')
child['multiply'].setExpression('%s.multiply' % parent.name())
This is a lot cleaner, and would be represented visually in the node tree too.

module interconnection interface design

I want to have some simple interfaces for the users to connect some pre-defined modules (I'm free to modify them if I have to).
Each module has a few named inputs and outputs.
One module may connect to a few modules.
A few modules can connect to a single module.
This is what I have in my mind so far:
Option 1:
Each module has "in" and "out" dictionary for input and output, and the connection is made through code like this:
a.out["out 1"].to(b.in["in 1"]) # connect a's "out 1" output to b's "in 1" input
a.out["out 2"].to(b.in["in 2"]) # connect a's "out 2" output to b's "in 2" input
But this looks quite tedious, so I came up with Option 2:
# connect a to b and c, then list which inputs connect to which outputs
a.to(b,{"out 1":"in 1",
"out 2":"in 2"},
c,{"out 4":"in 1",
"out 3":"in 2"})
This seems to look better as it's clearer to me which modules are connected and also the mapping between their outputs and inputs are clearly listed.
I wonder if there is any room to improve the above, to clearly show:
module level connections, e.g. module a connect to module b
outputs and inputs connections
simple and clear interface. By 'simple', I mean less typing; 'clear' means easy to understand. I understand that sometimes I can't have both in that case, 'clear' interface is preferable.
I'm not proficient in Python(2.7) so there might be some syntax or operator or data structure that I am not aware of but I may be able to take advantage for this purpose.
I have run into this exact issue, the issue of being able to clearly describe directed graphs linearly. None are particularly pleasant... Personally, I believe showing how the sources and sinks (node inputs and outputs) connect is more important than showing which nodes are connected, because the relationship is more specific.
Of the two designs you listed I would recommend the first, since it is clearer. It shows exactly how each input and output connects. However, I would slightly augment your implementation. I would make the node class capable of creating new handles for inputs and outputs that are actual attributes in the object. Then use those handles when describing the graph and capturing traffic, etc. Making the inputs and outputs actual objects instead of labels means construction-time checking and the ability to generate better error messages. For example:
b = Node()
b.input("in1", "in2") # this creates a new input object that is located in 'b' with the attribute name of the given string
b.output("out1") # this could be in the constructor
c = Node(in=["in1", "in2"], out=["out1"]) # like so
# describe the connections
a.out1.to(b.in1)
a.out2.to(b.in2)
a.out3.to(c.in2)
a.out4.to(c.in1)
# maybe syntax like 'a.out3 >> c.in2' would be prettier?
module_graph_output = c.out1.capture()
# do stuff with the graph output
Additionally, the module definitions can be passed these output and input object handlers for the user as they implement the module logic.
All this aside, how you are going to run the module graph is the bigger issue. If I'm not intruding, what is the application of this?

grounding predicates with python scripts in asp/clingo

I am using clingo version 4 and wish to be able to ground relations via python script (please don't ask why, it's not a crime, since you can at least ground 1-ary relations). I am hoping this is possible, and need some help.
#script (python)
import gringo;
def main(prg):
prg.ground([('base', [])]);
# ... compute somethings ...
prg.ground([('myrel', [[10,20],[30,40],[70,40]])]);
prg.solve();
#end.
#program myrel(x,y).
r(x,y).
#show r/2.
this doesn't work. Does anyone know how to do this? I tried [(10,20),(30,40),(70,40)] instead, but that also did not work.
It is possible, but one has to input each entry one by one (which for my application is actually good). Instead of
prg.ground([('myrel', [[10,20],[30,40],[70,40]])]);
one has to write
prg.ground([('myrel', [10,20])]);
prg.ground([('myrel', [30,40])]);
prg.ground([('myrel', [70,40])]);
and then it is accepted and yields the right output.

Categories

Resources