Need help adding value to a variable - python

Here is the whole code section
for entry in auth_log:
# timestamp is converted to milliseconds for CEF
# repr is used to keep '\\' in the domain\username
extension = {
'rt=': str(time.ctime(int(entry['timestamp']))),
'src=': entry['ip'],
'dhost=': entry['host'],
'duser=': repr(entry['username']).lstrip("u").strip("'"),
'outcome=': entry['result'],
'cs1Label=': 'new_enrollment',
'cs1=': str(entry['new_enrollment']),
'cs2Label=': 'factor',
'cs2=': entry['factor'],
'ca3Label=': 'integration',
'cs3=': entry['integration'],
}
log_to_cef(entry['eventtype'], entry['eventtype'], **extension)
In line 5 (rt=), I would like to add the timestamp output to a variable where I can call it later in the script.

You can access the value from the dictionary directly with extension["rt="]?
If you are looking for a way to have a list of all the variables outside of your loop you can use this method.
Before your loop you should make an empty list like this:
extensionRt = []
Then after extension is created inside each loop use:
extensionRt.append(extension["rt="])
You can then access the values in this list by index:
extensionRt[YOUR INDEX HERE]

Related

Assigning a value from a dataframe to a dynamically created variable

I have a simple pandas dataframe with a column 'mycol' and has 5 rows in it and I'm trying to create 5 new variables for every row value, something like below:
newcol_1=df['mycol'][0]
newcol_2=df['mycol'][1]
newcol_3=df['mycol'][2]
newcol_4=df['mycol'][3]
newcol_5=df['mycol'][4]
I don't want to hard code as above and I'm using the below "for loop" but it keeps throwing 'can't assign to operator'. I know that assignment values should be on the right and variable on the left but not sure how do I use for loop to dynamically create these 5 variables.
for i in 0, df.shape[0]-1:
#"newcol_"+str(i+1) =df['mycol'][i] # this isn't working
newcol_+str(i+1) =df['mycol'][i] # this also isn't working
Appreciate if anyone can help with this...Thanks!
Preferred option: modify globals()
# Create variables dynamically
for i, value in enumerate(df["VALUE"].values):
globals()[f"newcol_{i+1}"] = value
# Test that newcol_3 exists, for instance
print(newcol_3) # Works fine
print(newcol_3 == df['mycol'][2]) # True
Alternate option: use exec()
Though one should do so with caution
# Create a new dict with desired key/value pairs
newcols = {f"newcol_{i+1}": value for i, value in enumerate(df["VALUE"].values)}
# Create new variables dynamically from dict
for name, value in newcols.items():
exec(f"{name}= {value}")
# Previous tests work just as fine

Create nested dictionaries during for loop

I have created a list during a for loop which works well but I want create a dictionary instead.
from System.Collections.Generic import List
#Collector
viewPorts = list(FilteredElementCollector(doc).OfClass(Viewport))
#create a dictionary
viewPortDict = {}
#add Sheet Number, View Name and boxoutline to dictionary
for vp in viewPorts:
sheet = doc.GetElement(vp.SheetId)
view = doc.GetElement(vp.ViewId)
vbox = vp.GetBoxOutline()
viewPortDict = {view.ViewName : {'sheetNum': sheet.SheetNumber, 'viewBox' : vbox}}
print(viewPortDict)
The output from this is as follows:
{'STEEL NOTES': {'viewBox': <Autodesk.Revit.DB.Outline object at 0x000000000000065A [Autodesk.Revit.DB.Outline]>, 'sheetNum': 'A0.07'}}
Which the structure is perfect but I want it to grab everything as while it does the for loop it seems to stop on the first loop. Why is that? And how can I get it to keep the loop going?
I have tried various things like creating another list of keys called "Keys" and list of values called "viewPortList" like:
dict.fromkeys(Keys, viewPortList)
But I always have the same problem I am not able to iterate over all elements. For full disclosure I am successful when I create a list instead. Here is what that looks like.
from System.Collections.Generic import List
#Collector
viewPorts = list(FilteredElementCollector(doc).OfClass(Viewport))
#create a dictionary
viewPortList = []
#add Sheet Number, View Name and boxoutline to dictionary
for vp in viewPorts:
sheet = doc.GetElement(vp.SheetId)
view = doc.GetElement(vp.ViewId)
vbox = vp.GetBoxOutline()
viewPortList.append([sheet.SheetNumber, view.ViewName, vbox])
print(viewPortList)
Which works fine and prints the below (only portion of a long list)
[['A0.01', 'APPLICABLE CODES', <Autodesk.Revit.DB.Outline object at 0x000000000000060D [Autodesk.Revit.DB.Outline]>], ['A0.02', etc.]
But I want a dictionary instead. Any help would be appreciated. Thanks!
In your list example, you are appending to the list. In your dictionary example, you are creating a new dictionary each time (thus removing the data from previous iterations of the loop). You can do the equivalent of appending to it as well by just assigning to a particular key in the existing dictionary.
viewPortDict[view.ViewName] = {'sheetNum': sheet.SheetNumber, 'viewBox' : vbox}

Parsing and arranging text in python

I'm having some trouble figuring out the best implementation
I have data in file in this format:
|serial #|machine_name|machine_owner|
If a machine_owner has multiple machines, I'd like the machines displayed in a comma separated list in the field. so that.
|1234|Fred Flinstone|mach1|
|5678|Barney Rubble|mach2|
|1313|Barney Rubble|mach3|
|3838|Barney Rubble|mach4|
|1212|Betty Rubble|mach5|
Looks like this:
|Fred Flinstone|mach1|
|Barney Rubble|mach2,mach3,mach4|
|Betty Rubble|mach5|
Any hints on how to approach this would be appreciated.
You can use dict as temporary container to group by name and then print it in desired format:
import re
s = """|1234|Fred Flinstone|mach1|
|5678|Barney Rubble|mach2|
|1313|Barney Rubble||mach3|
|3838|Barney Rubble||mach4|
|1212|Betty Rubble|mach5|"""
results = {}
for line in s.splitlines():
_, name, mach = re.split(r"\|+", line.strip("|"))
if name in results:
results[name].append(mach)
else:
results[name] = [mach]
for name, mach in results.items():
print(f"|{name}|{','.join(mach)}|")
You need to store all the machines names in a list. And every time you want to append a machine name, you run a function to make sure that the name is not already in the list, so that it will not put it again in the list.
After storing them in an array called data. Iterate over the names. And use this function:
data[i] .append( [ ] )
To add a list after each machine name stored in the i'th place.
Once your done, iterate over the names and find them in in the file, then append the owner.
All of this can be done in 2 steps.

Adding keys with empty values and then adding values in a nested format in python

I am trying to create and add elements to a dictionary in the following format,
{{"source1": { "destination11": ["datetime1", "datetime2", ....]}
{ "destination12": ["datetime3", "datetime4",....]}
........................................
}
{"source2": { "destination21": ["datetime5", "datetime6", ....]}
{ "destination22": ["datetime7", "datetime8",....]}
.......................................
}
.........................................}
All the keys and values are variables which I am getting from other modules.
I have created an empty dictionary
call_record=[{}]
To add the "source1", "source2" as keys I tried,
call_record.append({source1 :})
Now i can't add a value to this key yet because i will be adding it in the next lines, so I need to create this key with empty value and then add values as I get them from the next modules. But, this line doesn't create a key with empty value.
Besides, to add "destination11", "destination12"ets, I tried,
call_record[i].append(destination11)
But, this doesn't add the destinations as the values of the source key.
I have to add the datetimes, after I have added the destinations. Then I have to dump this dictionary in a json file.
.append is used to add an element to an array.
The correct sintax to add an element to a dictionary is your_dictionary[key] = value
In your case you can pass the arguments to your dictionary as follow:
import json
call_record = {} # To create an empty dictionary
call_record["source1"] = {} # To append an empty dictionary to the key "source1"
call_record["source1"]["destination11"] = [] # An empty array as value for "destination11"
call_record["source1"]["destination11"].append("datetime1", "datetime2") # To append element datetime1 and datetime2 to destination11 array
call_record_json = json.dumps(call_record, ensure_ascii=False)
I would however suggest to have a look at the python documentation to clarify the data structure in python.
You can also refer to JSON encoder and decoder section of the documentation for further examples about how to use it.

use slice in for loop to build a list

I would like to build up a list using a for loop and am trying to use a slice notation. My desired output would be a list with the structure:
known_result[i] = (record.query_id, (align.title, align.title,align.title....))
However I am having trouble getting the slice operator to work:
knowns = "output.xml"
i=0
for record in NCBIXML.parse(open(knowns)):
known_results[i] = record.query_id
known_results[i][1] = (align.title for align in record.alignment)
i+=1
which results in:
list assignment index out of range.
I am iterating through a series of sequences using BioPython's NCBIXML module but the problem is adding to the list. Does anyone have an idea on how to build up the desired list either by changing the use of the slice or through another method?
thanks zach cp
(crossposted at [Biostar])1
You cannot assign a value to a list at an index that doesn't exist. The way to add an element (at the end of the list, which is the common use case) is to use the .append method of the list.
In your case, the lines
known_results[i] = record.query_id
known_results[i][1] = (align.title for align in record.alignment)
Should probably be changed to
element=(record.query_id, tuple(align.title for align in record.alignment))
known_results.append(element)
Warning: The code above is untested, so might contain bugs. But the idea behind it should work.
Use:
for record in NCBIXML.parse(open(knowns)):
known_results[i] = (record.query_id, None)
known_results[i][1] = (align.title for align in record.alignment)
i+=1
If i get you right you want to assign every record.query_id one or more matching align.title. So i guess your query_ids are unique and those unique ids are related to some titles. If so, i would suggest a dictionary instead of a list.
A dictionary consists of a key (e.g. record.quer_id) and value(s) (e.g. a list of align.title)
catalog = {}
for record in NCBIXML.parse(open(knowns)):
catalog[record.query_id] = [align.title for align in record.alignment]
To access this catalog you could either iterate through:
for query_id in catalog:
print catalog[query_id] # returns the title-list for the actual key
or you could access them directly if you know what your looking for.
query_id = XYZ_Whatever
print catalog[query_id]

Categories

Resources