I'm using the collection.Counter function to create a dictionary of paths to its listing of its mime types in order. It's a great little module, however the Counter doesn't change it's values from path to path.
I have a dictionary called package_mime_types that each entry looks like this:
package_mime_types['/a/path/to/somewhere'] = [('text/plain'),('text/plain'),('application/msword')]...
As you can imagine, the values in that dictionary are very long. I'm trying to convert it to a listing like this:
package_mime_types['/a/path/to/somewhere'] = ['text/plain':780, 'application/msword':400, 'audio/mp3':30]
This is my little iteration that's supposed to do that:
for package_path, mime_types_list in package_mime_types.items():
c = collections.Counter(mime_types_list)
package_mime_types[package_path] = c
return package_mime_types
The end result works, but all the Counter arrays are the exact same for each path.
/path1/ relates to Counter({'text/plain': 2303, 'audio/x-wav': 90, 'text/html': 17, 'application/msword': 17, 'application/x-trash': 6, 'application/x-tar': 4, 'application/xml': 1, 'text/x-sh': 1})
/path2/ relates to Counter({'text/plain': 2303, 'audio/x-wav': 90, 'text/html': 17, 'application/msword': 17, 'application/x-trash': 6, 'application/x-tar': 4, 'application/xml': 1, 'text/x-sh': 1})
/path3/ relates to Counter({'text/plain': 2303, 'audio/x-wav': 90, 'text/html': 17, 'application/msword': 17, 'application/x-trash': 6, 'application/x-tar': 4, 'application/xml': 1, 'text/x-sh': 1})
/path4/ relates to Counter({'text/plain': 2303, 'audio/x-wav': 90, 'text/html': 17, 'application/msword': 17, 'application/x-trash': 6, 'application/x-tar': 4, 'application/xml': 1, 'text/x-sh': 1})
/path5/ relates to Counter({'text/plain': 2303, 'audio/x-wav': 90, 'text/html': 17, 'application/msword': 17, 'application/x-trash': 6, 'application/x-tar': 4, 'application/xml': 1, 'text/x-sh': 1})
Am I missing something with using the Counter?
I'm facepalming myself right now. It wasn't a problem with the Counter at all but rather the iteration I was doing to create the listing of the file types. I didn't make a new array each time the iteration was populating my dictionary. So all of the files were associated with each path.
def find_mimes(package_paths):
package_mime_types = {}
mime_types_list =[]
## Walking through directories looking for the mime types
for package_path in package_paths:
print(package_path, "is being walked through")
for root, dirs, files in os.walk(package_path, followlinks = True):
for file in files:
if mimetypes.guess_type(os.path.join(root, file)) != (None, None):
mime_types_list.append(mimetypes.guess_type(os.path.join(root, file))[0])
package_mime_types[package_path] = mime_types_list
See how mime_types_list is above the iteration? It was a static variable. Moving into the package_path loop fixed it.
def find_mimes(package_paths):
package_mime_types = {}
## Walking through directories looking for the mime types
for package_path in package_paths:
##Setting mime_types_list array back to empty for every path. (Duh)
##Now mime_types_list will be empty before the walking starts
mime_types_list =[]
print(package_path, "is being walked through")
for root, dirs, files in os.walk(package_path, followlinks = True):
for file in files:
if mimetypes.guess_type(os.path.join(root, file)) != (None, None):
mime_types_list.append(mimetypes.guess_type(os.path.join(root, file))[0])
package_mime_types[package_path] = mime_types_list
Related
I'm learning Python and had a small issue. I have this loop:
found = None
print ('Before', found)
for value in [ 41, 5, 77, 3, 21, 55, 6]:
if value == 21:
found = True
else:
found = False
print (found, value)
print ('After', found)
The code is well, but the issue is print ('After', found) I want it to tell me that there was a True value found in the loop. Is there a way to keep the code the way it is and resolve the issue?
You don't want to reset found to False once you've set it to True. Initialize it to False, then only set it to True if value == 21; don't do anything if value != 21.
found = False
print ('Before', found)
for value in [ 41, 5, 77, 3, 21, 55, 6]:
if value == 21:
found = True
print (found, value)
print ('After', found)
Ignoring the print statement in the loop, you could just use any:
found = any(value == 21 for value in [ 41, 5, 77, 3, 21, 55, 6])
or even
found = 21 in [ 41, 5, 77, 3, 21, 55, 6]
class CustomOrderFilter(OrderingFilter):
allowed_custom_filters = ['target_item__type_service', 'target_item__level', 'target_item__room__name',
'client__user_full_name', 'designer__user_full_name', 'status', 'date_due_decorist',
'target_item__date_answered']
def get_ordering(self, request, queryset, view):
params = request.query_params.get(self.ordering_param)
if params:
fields = [param.strip() for param in params.split(',')]
ordering = [f for f in fields if f.lstrip('-') in self.allowed_custom_filters]
if ordering:
return ordering
return self.get_default_ordering(view)
def filter_queryset(self, request, queryset, view):
order_fields = []
ordering = self.get_ordering(request, queryset, view)
if not ordering:
return queryset
order_fields.append(ordering[0])
if 'status' in order_fields or '-status' in order_fields:
ids = [0, 1, 2, 18, 3, 6, 9, 7, 21, 5, 8, 11, 12, 10, 14, 15, 16, 20, 4, 13, 17]
rev_ids = [11, 8, 5, 21, 7, 9, 6, 3, 18, 2, 1, 0, 12, 10, 14, 15, 16, 20, 4, 13, 17]
if '-status' in order_fields:
order = Case(*[When(status=id, then=pos) for pos, id in enumerate(rev_ids)])
else:
order = Case(*[When(status=id, then=pos) for pos, id in enumerate(ids)])
return queryset.order_by(order)
if '-date_due_decorist' in order_fields:
return queryset.order_by(F('date_due_decorist').desc(nulls_last=True))
elif 'date_due_decorist' in order_fields:
return queryset.order_by(F('date_due_decorist').asc(nulls_last=True))
return queryset.order_by(ordering[0])
In custom ordering django, I am getting error as "asc() got an unexpected keyword argument 'nulls_last' ". I want to show null values always at last in date_due_decorist column while sorting. Please let me know if django version 1.10 supports 'nulls_last' or not.
If not support then let me know how can this be done?
I'm trying to print a select row and columns from a spreadsheet, however when I call on the spreadsheet dataframe attribute it fails to print state that the name dataframe is not defined. where have I gone wrong?
import pandas
class spreadsheet:
def __init__(self, location, dataframe, column, rows):
self.location = ('Readfrom.xlsx')
self.dataframe = pandas.read_excel(location)
self.column = 2
self.rows = 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 27, 28, 29
a = dataframe.iloc[column,[rows]]
print(a)
You should instantiate an object from the Spreadsheet class and then access the attribute of the instance. You can learn more about Object-Oriented Programming in Python here.
I think that what you want to do in your code is something like the code below.
import pandas
class Spreadsheet:
def __init__(self, location):
self.location = location
self.dataframe = pandas.read_excel(location)
sp = Spreadsheet(location="Readfrom.xlsx")
rows = [4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 27, 28, 29]
a = sp.dataframe.iloc[rows, 2]
print(a)
I think you have an indentation problem.
Your dataframe is a parameter of your spreadsheet constructor method and you try to access it even from outside the class.
To access the dataframe variable u have to move your code a = dataframe.iloc[column,[rows]] inside your __init__ method or you need to create a spreadsheet object first and access it via this object.
EDIT:
On second thoughts i think you should check out the basics how to use classes in Python.
You don't use the parameters of the __init__ so why du you have them?
dataframe is only accessible by a spreadsheet object
This code should fix your problem but i recommend to go through some basic tutorials to understand how exactly classes and objects are working:
import pandas
class spreadsheet:
def __init__(self):
self.location = ('Readfrom.xlsx')
self.dataframe = pandas.read_excel(self.location)
self.column = 2
self.rows = 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 27, 28, 29
s = spreadsheet()
a = s.dataframe.iloc[s.column,[s.rows]]
print(a)
In Excel cell text will vary from Pass to Fail.I have to give background color green for Pass(pass/Passed/passed) and red for Fail(fail/Failed/failed) respectively. How to change the color based on text ?
My Script
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('Testing')
worksheet.write_merge(5, 5, 1, 1,'S.No')
worksheet.write_merge(5, 5, 2, 2,'Test Case Description')
worksheet.write_merge(5, 5, 3, 3,'Status')
worksheet.write_merge(5, 5, 4, 4,'Remarks')
worksheet.write_merge(6, 6, 1, 1,1)
worksheet.write_merge(7, 7, 1, 1,1)
worksheet.write_merge(6, 6, 2, 2,'Verify Transferring rate')
worksheet.write_merge(7, 7, 2, 2,'Verify Receiving rate')
worksheet.write_merge(6, 6, 3, 3,'Pass')
worksheet.write_merge(7, 7, 3, 3,'Fail')
workbook.save('testexcel.xls')
#Henry:
Modified code :
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('Status')
passed = xlwt.easyxf('back_color green')
failed = xlwt.easyxf('back_color red')
color = (passed if passorfail in ['pass','Passed','passed'] else
(failed if passorfail in ['fail','Failed','failed'] else xlwt.easyxf()))
worksheet.write_merge(6, 6, 3, 3,passorfail, style = color)
workbook.save('passfail2.xls')
print "Completed"
And it's throwing error when execute ? How to resolve this error ?
Traceback (most recent call last):
File "G:\airspan_eclipse\Excel_Gen\passfail2.py", line 5, in <module>
passed = xlwt.easyxf('back_color green')
File "C:\Python27\lib\site-packages\xlwt\Style.py", line 704, in easyxf
field_sep=field_sep, line_sep=line_sep, intro_sep=intro_sep, esc_char=esc_char, debug=debug)
File "C:\Python27\lib\site-packages\xlwt\Style.py", line 632, in _parse_strg_to_obj
raise EasyXFCallerError('line %r should have exactly 1 "%c"' % (line, intro_sep))
xlwt.Style.EasyXFCallerError: line 'back_color green' should have exactly 1 ":"
You can create styles using easyxf and then pass them as arguments to your write method.
For example:
style_pass = xlwt.easyxf('pattern: pattern solid, fore_colour green;')
style_fail = xlwt.easyxf('pattern: pattern solid, fore_colour red;')
worksheet.write_merge(6, 6, 3, 3,'Pass', style=style_pass)
worksheet.write_merge(7, 7, 3, 3,'Fail', style=style_fail)
You'll need to put in a if statement to seperate pased on pass fail.
Then, you'll use that to make a color string, something like 'fore-colour grey25'. Look in Style.py for lists of all possible colors and options (github page: https://github.com/python-excel/xlwt/blob/master/xlwt/Style.py). Since red and green both work, and back_color also works, you can do:
passed = xlwt.easyxf('back_color green')
failed = xlwt.easyxf('back_color red')
color = (passed if passorfail in ['pass','Passed','passed'] else
(failed if passorfail in ['fail','Failed','failed'] else xlwt.easyxf()))
worksheet.write_merge(6, 6, 3, 3,passorfail, style = color)
I've got a little problem:
I have a String in my Database which is called actions.
Now, I'm writing a method, which gets that string from the database
(that works), and then I want to turn that string into a list.
I know actions.split(), but this didn't work out so well for me, because if my string looks like this:
actions = [
{u'action': 'visit_testing', u'timestamp': datetime.datetime(2016, 2, 12, 13, 32, 14)},
{u'action': 'visit_foo', u'timestamp': datetime.datetime(2016, 2, 12, 13, 37, 50)}
]
I can't use actions.split(', ') because it would mess up the dictionaries inside.
Till now I've got the following code:
timestamp = datetime.now().replace(microsecond=0)
dict = {'timestamp': timestamp, 'action': action}
if self.actions:
actions_string = str(self.actions)
actions_stripped = actions_string.strip('[')
actions_stripped = actions_stripped.strip(']')
actions_splitted = actions_stripped.split(', ')
new_action_list = []
buffer = ''
for string in actions_splitted:
if '{' in string:
buffer = str(string)
elif '}' in string:
buffer = buffer + ', ' + str(string)
new_action_list.append(str(buffer))
buffer = ''
else:
buffer = buffer + ', ' + str(string)
self.actions = str(buffer)
self.last_action = datetime.now().replace(microsecond=0)
self.save()
else:
self.actions = '['+str(dict)+']'
self.last_action = datetime.now().replace(microsecond=0)
self.save()
Addition: If I run the method when actions is empty, it gives me a list with one dictionary, but if I run it when it already has something in it, if sets actions to "".
You should be using the json module to store valid JSON in your database. You can create a valid action list from that string using exec. But please beware that using exec or eval is a potentially dangerous practice.
import datetime
stuff = '''
actions = [{u'action': 'visit_testing', u'timestamp': datetime.datetime(2016, 2, 12, 13, 32, 14)}, {u'action': 'visit_foo', u'timestamp': datetime.datetime(2016, 2, 12, 13, 37, 50)}]
'''
exec(stuff)
print(actions)
print(actions[0]['timestamp'])
output
[{u'action': 'visit_testing', u'timestamp': datetime.datetime(2016, 2, 12, 13, 32, 14)}, {u'action': 'visit_foo', u'timestamp': datetime.datetime(2016, 2, 12, 13, 37, 50)}]
2016-02-12 13:32:14
Use json library.
import json
my_dict_or_list = json.loads(your_string)
then work with Python objects. You will gain so much time :-D
I found a way that works for me:
timestamp = datetime.datetime.now().replace(microsecond=0)
if self.actions:
new_dict = {"timestamp": timestamp, "action": action}
#tmp_actions = json.loads(self.actions)
tmp_actions = self.actions
exec(tmp_actions)
actions.append(new_dict)
self.actions = str('actions = '+str(actions))
self.last_action = datetime.datetime.now().replace(microsecond=0)
self.save()
else:
exec('''actions = ['''+str({"timestamp": timestamp, "action": action})+''']''')
self.actions = 'actions = '+str(actions)
self.last_action = datetime.datetime.now().replace(microsecond=0)
self.save()
Thanks for all the help.