I had a huge registration table with 112 fields. For a particular search I want to compare 17 fields & assign colors to variable say 'clrSelected'.
My code is :
reg = Regisration.objects.filter('some condition').order_by("name")
for r in reg:
if r.name=='abc': clrSelected='#fff'
if r.type=='1': clrSelected='#000'
if r.appl=='10': clrSelected='#c1ff51'
if r.code=='': clrSelected='#60c5f7'
if r.qlty=='first': clrSelected='#f99334'
...
...
there will be only one if condition, which need to be colored. Which means the field(from the dictionary) to be compared will change based on the user selection.
I want to access the field name from a dictionary like this
flds = {'1':'name', '2':'type', '3':'appl', '4':'code', '5':'qlty',...}
And use it something like this
if r.flds['1']=='abc': clrSelected='#fff'
How could i use the fields as above. I am using django 1.4 & python 2.7
Just to answer the question, you could use getattr:
if getattr(r, flds['1']) == 'abc': clrSelected = '#fff'
However, I am pretty sure that you could go with a different kind of implementation in this case which doesn't require using a dict like this.
I would suggest using a three tuple list: (fieldName, value, color)
some_list = [('name', 'abc', '#fff'), ('type', '1', '#000'), ...]
And, then use this list to determine the color:
for fieldName, value, color in some_list:
if getattr(r, fieldName) == value:
clrSelected = color
Looking at your implementation, it seems the color will be based on the last if condition which matches. If that is the case, you could create some_list in reverse order and break on the first matching condition.
Related
I am new to python and my coding experience so far is with MATLAB.
I am trying to understand more about lists and dictionaries as i am using a library about DOEs that takes an dictionary as a passing argument.
But my trouble so far is that this dictionary assumes the form of ex.
DOE={'Elastic Modulus':[10,20,30], 'Density':[1,2,3], 'Thickness':[2,3,5]}
But i need this dictionary to be user defined, for example:
Have an input to define how many variables are needed (in this example are 3: Elastic Modulus','Density'and 'Thickness)
as the variables are defined, it should be able to store values in the dictionary over a for loop.
Is this possible using dictionaries?
Or is it better to use a list and convert in a dicionary later?
Thank you in advance
One can add keys and the corresponding values to a dict one at a time like so:
my_dict = {}
num_entries = int(input("How many entries "))
for _ in range(num_entries):
key = input("Enter the key: ")
value = input("Enter the value: ")
my_dict[key] = value
Presumably you would have a loop to do the entry of key and value for the number of values you wish to enter. Also if you are in python 2 it needs to be raw_input rather than input function. [Edit: Showing how to do the loop, since I noticed that was part of your question]
I have a query sequence that I blasted online using NCBIWWW.qblast. In my xml blast file result I obtained for a query sequence a list of hit (i.e: gi|). Each hit or gi| have multiple hsp. I made a dictionary my_dict1 where I placed gi| as key and I appended the bit score as value. So multiple values for each key.
my_dict1 = {
gi|1002819492|: [437.702, 384.47, 380.86, 380.86, 362.83],
gi|675820360| : [2617.97, 2614.37, 122.112],
gi|953764029| : [414.258, 318.66, 122.112, 86.158],
gi|675820410| : [450.653, 388.08, 386.27] }
Then I looked for max value in each key using:
for key, value in my_dict1.items():
max_value = max(value)
And made a second dictionary my_dict2:
my_dict2 = {
gi|1002819492|: 437.702,
gi|675820360| : 2617.97,
gi|953764029| : 414.258,
gi|675820410| : 450.653 }
I want to compare both dictionary. So I can extract the hsp with the highest score bits. I am also including other parameters like query coverage and identity percentage (Not shown here). The finality is to get the best gi| with the highest bit scores, coverage and identity percentage.
I tried many things to compare both dictionary like this :
First code :
matches[]
if my_dict1.keys() not in my_dict2.keys():
matches[hit_id] = bit_score
else:
matches = matches[hit_id], bit_score
Second code:
if hit_id not in matches.keys():
matches[hit_id]= bit_score
else:
matches = matches[hit_id], bit_score
Third code:
intersection = set(set(my_dict1.items()) & set(my_dict2.items()))
Howerver I always end up with 2 types of errors:
1 ) TypeError: list indices must be integers, not unicode
2 ) ... float not iterable...
Please I need some help and guidance. Thank you very much in advance for your time. Best regards.
It's not clear what you're trying to do. What is hit_id? What is bit_score? It looks like your second dict is always going to have the same keys as your first if you're creating it by pulling the max value for each key of the first dict.
You say you're trying to compare them, but don't really state what you're actually trying to do. Find those with values under a certain max? Find those with the highest max?
Your first code doesn't work because I'm assuming you're trying to use a dict key value as an index to matches, which you define as a list. That's probably where your first error is coming from, though you haven't given the lines where the error is actually occurring.
See in-code comments below:
# First off, this needs to be a dict.
matches{}
# This will never happen if you've created these dicts as you stated.
if my_dict1.keys() not in my_dict2.keys():
matches[hit_id] = bit_score # Not clear what bit_score is?
else:
# Also not sure what you're trying to do here. This will assign a tuple
# to matches with whatever the value of matches[hit_id] is and bit_score.
matches = matches[hit_id], bit_score
Regardless, we really need more information and the full code to figure out your actual goal and what's going wrong.
I'm trying to create a model where one of the fields should be an Age field, but that instead of being a simple number (IntegerField), I needed to be a Choice of several available age ranges (5-8, 8-12, 12-18, 18-99, 5-99). I'm looking at the documentation of Choices, but I'm not even sure I can use directly an IntegerRangeField in this, so I ended up with something like this:
class Person(models.Model):
FIRST_RANGE = IntegerRangeField(blank=True, validators=[MinValueValidator(5), MaxValueValidator(8)])
SECOND_RANGE = IntegerRangeField(blank=True, validators=[MinValueValidator(8), MaxValueValidator(12)])
THIRD_RANGE = IntegerRangeField(blank=True, validators=[MinValueValidator(12), MaxValueValidator(18)])
FOURTH_RANGE = IntegerRangeField(blank=True, validators=[MinValueValidator(18), MaxValueValidator(99)])
FIFTH_RANGE = IntegerRangeField(blank=True, validators=[MinValueValidator(18), MaxValueValidator(99)])
AGE_CHOICES = (
(FIRST_RANGE, '5-8'),
(SECOND_RANGE, '8-12'),
(THIRD_RANGE, '12-18'),
(FOURTH_RANGE, '18-99'),
(FIFTH_RANGE, '5-99'),
)
age = models.IntegerRangeField(blank=True, choices=AGE_CHOICES)
Is this the correct approach for this? This looks a bit awkward to me, I'm considering just using Char instead, although I'd like to stick to a have a Range on this field at the end...
Thanks!
From the documentation of Range Fields in django:
All of the range fields translate to psycopg2 Range objects in python, but also accept tuples as input if no bounds information is necessary. The default is lower bound included, upper bound excluded.
It seems you can use tuples to create the choices.
FIRST_RANGE = (5, 8) # here 5 is included and 8 is excluded
# and similarly create the other ranges and then use in AGE_CHOICES
Alternatively, you can create the Range objects.
from psycopg2.extras import Range
FIRST_RANGE = Range(lower=5, upper=8, bounds='[)')
# bounds: one of the literal strings (), [), (], [], representing whether the lower or upper bounds are included
How can i compare two dictionary and based on the matching keys I have to display the images. I mean if the key matched with the first dictionary and its in the second too, then i have to take the image based on the key. I have given a try, and the code is:
for key in res_lst_srt:
if key in resizedlist:
b,g,r = cv2.split(images[i])
img = cv2.merge((r,g,b))
plt.subplot(2,3,i+1),plt.imshow(img)
plt.xticks([]),plt.yticks([])
plt.show()
I have taken the query image seperately, and i have got the distance between the query image,and all the database image. Distance have key and value, database image have key and value. I want to retrieve the image which matches the best with minimum distance based on key.
Thanks in advance!
It seems to me that you are not properly into the dict concept, you should study it a little bit to understand how it works with simple elements (number, strings) and only when you got it try with the heavy datas as opencv images.
Try this piece of code:
dict1 = {'a':1, 'b':2, 'c':3}
dict2 = {'e':1, 'd':2, 'c':4}
print dict1
print dict2
# note that this code is not optimized!!
# there are plenty of ways you can do better
# but prob. is the easiest way == better way to understand it
for k1 in dict1.keys():
for k2 in dict2.keys():
if k1==k2:
print 'keys matches'
mergedvalues = dict1[k1] + dict2[k2]
print 'merged value is:', merged values
for better ways to compare two dicts going deep in python way of handling dict and other data structures (as list, set, etc) and operations on that, this answer is nice. but I think you should understand how dict works before.
Nearly every kind of lookup in Django has a case-insensitive version, EXCEPT in, it appears.
This is a problem because sometimes I need to do a lookup where I am certain the case will be incorrect.
Products.objects.filter(code__in=[user_entered_data_as_list])
Is there anything I can do to deal with this? Have people come up with a hack to work around this issue?
I worked around this by making the MySQL database itself case-insensitive. I doubt that the people at Django are interested in adding this as a feature or in providing docs on how to provide your own field lookup (assuming that is even possible without providing code for each db backend)
Here is one way to do it, admittedly it is clunky.
products = Product.objects.filter(**normal_filters_here)
results = Product.objects.none()
for d in user_entered_data_as_list:
results |= products.filter(code__iexact=d)
If your database is MySQL, Django treats IN queries case insensitively. Though I am not sure about others
Edit 1:
model_name.objects.filter(location__city__name__in': ['Tokio','Paris',])
will give following result in which city name is
Tokio or TOKIO or tokio or Paris or PARIS or paris
If it won't create conflicts, a possible workaround may be transforming the strings to upper or lowercase both when the object is saved and in the filter.
Here is a solution that do not require case-prepared DB values.
Also it makes a filtering on DB-engine side, meaning much more performance than iterating over objects.all().
def case_insensitive_in_filter(fieldname, iterable):
"""returns Q(fieldname__in=iterable) but case insensitive"""
q_list = map(lambda n: Q(**{fieldname+'__iexact': n}), iterable)
return reduce(lambda a, b: a | b, q_list)
The other efficient solution is to use extra with quite portable raw-SQL lower() function:
MyModel.objects.extra(
select={'lower_' + fieldname: 'lower(' + fieldname + ')'}
).filter('lover_' + fieldname + '__in'=[x.lower() for x in iterable])
Another solution - albeit crude - is to include the different cases of the original strings in the list argument to the 'in' filter. For example: instead of ['a', 'b', 'c'], use ['a', 'b', 'c', 'A', 'B', 'C'] instead.
Here's a function that builds such a list from a list of strings:
def build_list_for_case_insensitive_query(the_strings):
results = list()
for the_string in the_strings:
results.append(the_string)
if the_string.upper() not in results:
results.append(the_string.upper())
if the_string.lower() not in results:
results.append(the_string.lower())
return results
A lookup using Q object can be built to hit the database only once:
from django.db.models import Q
user_inputed_codes = ['eN', 'De', 'FR']
lookup = Q()
for code in user_inputed_codes:
lookup |= Q(code__iexact=code)
filtered_products = Products.objects.filter(lookup)
A litle more elegant way would be this:
[x for x in Products.objects.all() if x.code.upper() in [y.upper() for y in user_entered_data_as_list]]
You can do it annotating the lowered code and also lowering the entered data
from django.db.models.functions import Lower
Products.objects.annotate(lower_code=Lower('code')).filter(lower_code__in=[user_entered_data_as_list_lowered])