I am using this library to interact with Active Directory in Python:
http://timgolden.me.uk/python/ad_cookbook.html
I am trying to access the group names like this:
groups = []
for group in active_directory.search(objectClass='group'):
groups.append(str(group.cn))
My first issue is that group.cn gets the display name of the group instead of the actual object name. How do I get the object name?
My second issue is that running this code takes up HUGE amounts of memory. When there are thousands of groups in Active Directory, my program will use hundreds of megs or even a gig or two of memory. This is especially true when there are groups nested inside other groups. Is there a reason why after I've gotten all the group names, I am still using all that memory?
This is what I ended up doing:
results = None
try:
connection = ldap.open(str(self.hostnameLineEdit.text()))
connection.simple_bind_s(str(self.usernameLineEdit.text()), str(self.passwordLineEdit.text()))
userDNSDomain = os.environ['USERDNSDOMAIN']
userDNSDomain = userDNSDomain.split('.')
base = ""
for dc in userDNSDomain:
base += "dc=" + dc + ","
base = base[:-1]
#print base
resultID = connection.search(base,ldap.SCOPE_SUBTREE,'(objectClass=group)')
resultTypes, results = connection.result(resultID, 0)
except ldap.LDAPError, e:
self.messageBox("LDAP Error: " + str(e))
if results != None:
while results[0][0] != None:
#print results[0][1]['cn']
self.groupsListWidget.addItem(QString(results[0][1]['cn'][0]))
resultTypes, results = connection.result(resultID, 0)
Related
I'm currently trying to get into Python and Ren'Py a bit. Since I like to design a lot dynamically
and don't want to use copy&paste so often, I'm trying to create a page that will have ImageButtons with the corresponding number I specify.
In the example below I use "4" - but this can be higher.
I have built a class for this purpose:
Example:
init python:
class PictureSettings(object):
def __init__ (self, ImgIdle, ImgHover, LabelCall):
self.ImgIdle = ImgIdle
self.ImgHover = ImgHover
self.LabelCall = LabelCall
return
For the Idle/Hover and for the Jump.
If I insert in the code now in an object each entry "manually" with append I get all 4 pictures as desired indicated.
Example: (Works - but is not dynamic)
python:
var_pictures = []
var_pictures.append(PictureSettings("img_picture_1_idle", "img_picture_1_hover", "picture_1"))
var_pictures.append(PictureSettings("img_picture_2_idle", "img_picture_2_hover", "picture_2"))
var_pictures.append(PictureSettings("img_picture_3_idle", "img_picture_3_hover", "picture_3"))
var_pictures.append(PictureSettings("img_picture_4_idle", "img_picture_4_hover", "picture_4"))
I would like it to be like this:
Example (Here I get only ""img_picture_4_idle", "img_picture_4_hover", "picture_4""):
$ countlimit = 4
$ count = 1
python:
while count < countlimit:
var_pictures = []
var_pictures.append(PictureSettings(
ImgIdle = "img_picture_[count]_idle",
ImgHover = "img_picture_[count]_hover",
LabelCall = "picture_[count]"))
count += 1
Have already tried various things, unfortunately without success.
For example: with Add - instead of append (because this overwrites the result and leaves only the last entry
I get the following error:
var_pictures.add(PictureSettings( AttributeError: 'RevertableList' object has no attribute 'add')
Maybe someone can help me with the solution so I can keep my code dynamic without copying something X times.
Thanks for your help
You are creating your list inside your loop, so it is recreated every time.
At the end, you only get the last created list.
var_pictures = []
while count < countlimit:
var_pictures.append(PictureSettings(
ImgIdle = "img_picture_[count]_idle",
ImgHover = "img_picture_[count]_hover",
LabelCall = "picture_[count]"))
count += 1
On another subject, if you want to do this in a more pythonic way:
pictures = [] # no need for var_, we know its a variable
for i in range(1, 5):
pictures.append(PictureSettings(
# in python, we prefere snake_case attributes
img_idle=f'img_picture_{i}_idle',
img_hover=f'img_picture_{i}_hover',
...
))
# or even shorter with list comprehension
pictures = [
PictureSettings(
img_idle=f'img_picture_{i}_idle',
)
for i in range(1, 5)
]
By the way, no need to return in your class constructor
I have a rule that calculates new variables based on a set of variables, these variables are separated into different files. I have another rule for calculating the averages of all the different variables in the whole database. My problem is that snakemake tries to find my derived variables in the original database, which of course are not there.
Is there a way to have constrained the averaging rule such that it will calculate the average for all variables except for a list of the variables that are derived
Psudo code of how the rule look like
rule calc_average:
input:
pi_clim_var = lambda w: get_control_path(w, w.variable),
output:
outpath = outdir+'{experiment}/{variable}/{variable}_{experiment}_{model}_{freq}.nc'
log:
"logs/calc_average/{variable}_{model}_{experiment}_{freq}.log"
wildcard_constraints:
variable= '!calculated1!calculated2' # "orrvar1|orrvar2"....
notebook:
"../notebooks/calc_clim.py.ipynb"
I can of make a list of all the variables that I would like to have in the database and
then do:
wildcard_constraints:
variable="|".join(list_of_vars)
But I was wondering if it is possible to do it the other way round? E.g:
wildcard_constraints:
variable="!".join(negate_list_of_vars) # don't match these wildcards
EDIT:
The get_control_path(w, w.variable) constructs the path to the input file based on a lookup table that uses the wildcards as a keys.
def get_control_path(w, variable, grid_label=None):
if grid_label == None:
grid_label = config['default_grid_label']
try:
paths = get_paths(w, variable,'piClim-control', grid_label,activity='RFMIP', control=True)
except KeyError:
paths = get_paths(w, variable,'piClim-control', grid_label,activity='AerChemMIP', control=True)
return paths
def get_paths(w, variable,experiment, grid_label=None, activity=None, control=False):
"""
Get CMIP6 model paths in database based on the lookup tables.
Parameters:
-----------
w : snake.wildcards
a named tuple that contains the snakemake wildcards
"""
if w.model in ["NorESM2-LM", "NorESM2-MM"]:
root_path = f'{ROOT_PATH_NORESM}/{CMIP_VER}'
look_fnames = LOOK_FNAMES_NORESM
else:
root_path = f'{ROOT_PATH}/{CMIP_VER}'
look_fnames = LOOK_FNAMES
if activity:
activity= activity
else:
activity = LOOK_EXP[experiment]
model = w.model
if control:
variant=config['model_specific_variant']['control'].get(model, config['variant_default'])
else:
variant = config['model_specific_variant']['experiment'].get(model, config['variant_default'])
table_id = TABLE_IDS.get(variable,DEFAULT_TABLE_ID)
institution = LOOK_INSTITU[model]
try:
file_endings = look_fnames[activity][model][experiment][variant][table_id]['fn']
except:
raise KeyError(f"File ending is not defined for this combination of {activity}, {model}, {experiment}, {variant} and {table_id} " +
"please update config/lookup_file_endings.yaml accordingly")
if grid_label == None:
grid_label = look_fnames[activity][model][experiment][variant][table_id]['gl'][0]
check_path = f'{root_path}/{activity}/{institution}/{model}/{experiment}/{variant}/{table_id}/{variable}/{grid_label}'
if os.path.exists(check_path)==False:
grid_labels = ['gr','gn', 'gl','grz', 'gr1']
i = 0
while os.path.exists(check_path)==False and i < len(grid_labels):
grid_label = grid_labels[i]
check_path = f'{root_path}/{activity}/{institution}/{model}/{experiment}/{variant}/{table_id}/{variable}/{grid_label}'
i += 1
if control:
version = config['version']['version_control'].get(w.model, 'latest')
else:
version = config['version']['version_exp'].get(w.model, 'latest')
fname = f'{variable}_{table_id}_{model}_{experiment}_{variant}_{grid_label}'
paths = expand(
f'{root_path}/{activity}/{institution}/{model}/{experiment}/{variant}/{table_id}/{variable}/{grid_label}/{version}/{fname}_{{file_endings}}'
,file_endings=file_endings)
# Sometimes the verisons are just messed up... try one more time with latest
if not os.path.exists(paths[0]):
paths=expand(
f'{root_path}/{activity}/{institution}/{model}/{experiment}/{variant}/{table_id}/{variable}/{grid_label}/latest/{fname}_{{file_endings}}'
,file_endings=file_endings)
# Sometimes the file ending are different depending on varialbe
if not os.path.exists(paths[0]) and len(paths) >= 2:
paths = [paths[1]]
return paths
Your description is a little too abstract for me to fully grasp your intent. You may be able to use regex's to solve this, but depending on the number of variables to consider, it could be a very slow calculation to match. Here are some other ideas, if they don't seem right please update your question with a little more context (the rule requesting calc_average and the get_control_path function).
Place derived and original files in different subdirectories. Then you can restrict the average rule to just be the original files.
Incorporate the logic into an input function/expand. Say the requesting rule is doing something like
rule average:
input: expand('/path/to/{input}', input=[input for input in inputs if input not in negate_list_of_vars])
output: 'path/to/average'
I am running a function that grabs some data from a website and writes it into a pandas database. I am using selenium and geckodriver.
...code...
first_names = driver.find_elements_by_class_name('first-name')
first_names = [name.text for name in first_names]
last_names = driver.find_elements_by_class_name('last-name')
last_names = [name.text for name in last_names]
commit_status = driver.find_elements_by_class_name('school-name')
commit_status = [commit.text for commit in commit_status]
#error is happening below
athlete['commit_school'] = athlete['commit'].str.replace('\d+', '').str.replace('/',
'').str.replace('VERBAL', '').str.replace('SIGNED', '')
athlete['first'] = athlete['first'].str.title()
athlete['last'] = athlete['last'].str.title()
...code...
I then loop through this function to go through similar data on different states webpages. Sometimes it returns the data on the page normally and continues to the next state, while other times, I get:
AttributeError: Can only use .str accessor with string values!
...and the code breaks. The part that is confusing me is that the times I get the error seem to be arbitrary. Sometimes I will make it through 1/4 of the loop and sometimes 3/4 of the loop.
My first attempt to fix was a try/except, but I am not sure if I am doing it right or if that is the best approach:
athlete['state'] = state_all[:length:]
athlete['hs'] = hs_all[:length:]
athlete['commit'] = commit_status[:length:]
try:
athlete['commit_school'] = athlete['commit'].str.replace('\d+', '').str.replace('/',
'').str.replace('VERBAL', '').str.replace('SIGNED', '')
athlete['first'] = athlete['first'].str.title()
athlete['last'] = athlete['last'].str.title()
except AttributeError:
pass
athlete['list'] = 'Rivals_' + year + '_' + list_state
athlete['home'] = profile_page[:length:]
The error is happening within that try/except statement, but I think it just skips all of it if it finds an error.
Does the below code where I add .astype('str') to the middle for each column solve? You probably have column with mixed data type of strings and objects.
athlete['commit_school'] = athlete['commit'].astype('str').str.replace('\d+', '').str.replace('/', '').str.replace('VERBAL', '').str.replace('SIGNED', '')
athlete['first'] = athlete['first'].astype('str').str.title()
athlete['last'] = athlete['last'].astype('str').str.title()
After having read the following question and various answers ("Least Astonishment" and the Mutable Default Argument), as well as the official documentation (https://docs.python.org/3/tutorial/controlflow.html#default-argument-values), I've written my ResultsClass so that each instance of it has a separate list without affecting the defaults (at least, this is what should be happening from my new-gained understanding):
class ResultsClass:
def __init__(self,
project = None,
badpolicynames = None,
nonconformpolicydisks = None,
diskswithoutpolicies = None,
dailydifferences = None,
weeklydifferences = None):
self.project = project
if badpolicynames is None:
self.badpolicynames = []
if nonconformpolicydisks is None:
self.nonconformpolicydisks = []
if diskswithoutpolicies is None:
self.diskswithoutpolicies = []
if dailydifferences is None:
self.dailydifferences = []
if weeklydifferences is None:
self.weeklydifferences = []
By itself, this works as expected:
i = 0
for result in results:
result.diskswithoutpolicies.append("count is " + str(i))
print(result.diskswithoutpolicies)
i = i+1
['count is 0']
['count is 1']
['count is 2']
['count is 3']
etc.
The context of this script is that I'm trying to obtain information from each project within our Google Cloud infrastructure; predominantly in this instance, a list of disks with a snapshot schedule associated with them, a list of the scheduled snapshots of each disk within the last 24 hours, those that have bad schedule names that do not fit our naming convention, and the disks that do not have any snapshot schedules associated with them at all.
Within the full script, I use this exact same ResultsClass; yet when used within multiple for loops, the append again seems to be adding to the default values, and in all honesty I don't understand why.
The shortened version of the code is as follows:
# Code to obtain a list of projects
results = [ResultsClass() for i in range((len(projects)))]
for result in results:
for project in projects:
result.project = project
# Code to obtain each zone in the project
for zone in zones:
# Code to get each disk in zone
for disk in disks:
resourcepolicy = disk.get('resourcePolicies')
if resourcepolicy:
# Code to action if a resource policy exists
else:
result.badpolicynames.append(resourcepolicy[0].split('/')[-1])
result.nonconformpolicydisks.append(disk['id'])
else:
result.diskswithoutpolicies.append(disk['id'])
pprint(vars(result))
This then comes back with the results:
{'badpolicynames': [],
'dailydifferences': None,
'diskswithoutpolicies': ['**1098762112354315432**'],
'nonconformpolicydisks': [],
'project': '**project0**',
'weeklydifferences': None}
{'badpolicynames': [],
'dailydifferences': None,
'diskswithoutpolicies': ['**1098762112354315432**'],
['**1031876156872354739**'],
'nonconformpolicydisks': [],
'project': '**project1**',
'weeklydifferences': None}
Does a for loop (or multiple for loops) somehow negate the separate lists created within the ResultsClass? I need to understand why this is happening within Python and then how I can correct it.
Based on my best understanding, one of the glaring problem is you're nesting both the results and projects loop together, whereas you should be looping only either of those. I'd suggest looping the projects and creating a result in each instead of instantiating the classes in a list before.
results = []
for project in projects:
result = ResultsClass(project)
# Code to obtain each zone in the project
for zone in zones:
# Code to get each disk in zone
for disk in disks:
resourcepolicy = disk.get('resourcePolicies')
if resourcepolicy:
# Code to action if a resource policy exists
else:
result.badpolicynames.append(resourcepolicy[0].split('/')[-1])
result.nonconformpolicydisks.append(disk['id'])
else:
result.diskswithoutpolicies.append(disk['id'])
results.append(result)
pprint(vars(result))
With that, results is the list of your ResultsClass, and each result contain only one project, whereas your previous attempt would end with each ResultsClass with the same, last project.
I'm not sure if i get what you are trying to achieve correctly, but you are trying to transfer data from each project to a single result, right?
if so, you might want to use zip to have a single result per project:
for result, project in zip(results, projects):
# rest of the code
otherwise you are overriding the result for each previous project in the next loop iteration.
Another option would be to create the result in the loop:
results = []
for project in projects:
result = ResultsClass()
# ... your fetching code ...
results.append(result)
I've been using the following code to get the limits:
compute_limits = novaClient.limits.get().absolute
for s in compute_limits:
print s.name + " = " + str(s.value)
However I only want specific values from the limits.get(), namely totalRAMUsed and maxTotalRAMSize. There seems to be very little on the internet about using the Python API (mainly all about the CLI). Is there a way to get these specific values to avoid displaying all the limit values?
You can display only one specific value:
compute_limits = novaClient.limits.get().absolute
for s in compute_limits:
if s.name == 'totalRAMUsed':
print s.name + " = " + str(s.value)
break
compute_limits is generator, you can't receive only one specific value by limit name. But you can convert compute_limits to dict. For example:
compute_limits = novaClient.limits.get().absolute
l = list(compute_limits)
limits = dict(map(lambda x: (x.name, x.value), l))
print limits['totalRAMUsed']