Is this code okay design-wise? - django

I needed some OR filtering in my class method, but I feel really bad about this piece of code. Is this how it should be? Or can I design it somewhat better?
class FooBar:
#classmethod
def get_current_objects(cls, role='passenger',
add_params=None, offset=0, limit=10):
"""
The logic behind this is to return cls.objects with filters
defined in params var, but I stumbled accross
the need to use OR in the query, whilst keeping some `add_params`
in `params` var.
"""
params = {}
# ... here are some 'params', lots of code I need to keep, skipped ...
if add_params:
# this piece below feels awkward
for k, v in add_params.copy().iteritems():
if (v == True) and (role == 'passenger'):
add_args.append(Q(**{k: True}) | Q(**{k: False}))
del add_params[k]
elif (v == False) and (role == 'driver'):
add_args.append(Q(**{k: True}) | Q(**{k: False}))
del add_params[k]
elif (type(v) == str) and (role == 'passenger'):
add_args.append(Q(**{k: v}) | Q(**{k: u''}))
del add_params[k]
elif (type(v) == str) and (role == 'driver'):
add_args.append(Q(**{k: v}) | Q(**{k: u''}))
del add_params[k]
params.update(add_params)
# -----------------------------
return cls.objects.filter(*add_args, **params)[offset:offset + limit]
How do I not repeat myself in this circumstances?

I am not completely sure about the syntax, but this is how I would write it.
if add_params:
# this piece below feels awkward
for k, v in add_params.copy().iteritems():
if ((v == true) and (role == 'passenger')) # edited the true/false in
or ((v == false) and (role == 'driver')):
add_args.append(Q(**{k: True}) | Q(**{k: False}))
del add_params[k]
elif (type(v) == str) # (x or y) and (x or z) -> x and (y or z)
and ((role == 'passenger') or (role == 'driver')):
add_args.append(Q(**{k: v}) | Q(**{k: u''}))
del add_params[k]
params.update(add_params)
# -----------------------------
return cls.objects.filter(*add_args, **params)[offset:offset + limit]

Related

How to perform a nested When Otherwise in PySpark?

Hi Everyone , Im trying to interpret this PowerBi Syntax & Transform it into Pyspark
if(UCS_Incidents[Intensity]="Very High",
IF(UCS_Incidents[Severity]="Very High","Red",
IF(UCS_Incidents[Severity]="High","Red",
IF(UCS_Incidents[Severity]="Medium","Orange","Yellow"))),
if(UCS_Incidents[Intensity]="High",
IF(UCS_Incidents[Severity]="Very High","Red",
IF(UCS_Incidents[Severity]="High","Orange",
IF(UCS_Incidents[Severity]="Medium","Orange","Yellow"))),
if(UCS_Incidents[Intensity]="Medium",
IF(UCS_Incidents[Severity]="Very High","Orange",
IF(UCS_Incidents[Severity]="High","Yellow",
IF(UCS_Incidents[Severity]="Medium","Yellow","Green"))),
if(UCS_Incidents[Intensity]="Low",
IF(UCS_Incidents[Severity]="Very High","Yellow",
IF(UCS_Incidents[Severity]="High","Green",
IF(UCS_Incidents[Severity]="Medium","Green","Green"))),
""))))
And This is what i tried :
Intensities = df.withColumn(('Intensities',f.when((f.col('Intensity') == 'Very High') & (f.col('Severity') == 'Very High') , "Red").
otherwise(f.when((f.col('Intensity') == 'Very High') & (f.col('Severity') == 'High') , "Red").
otherwise(f.when((f.col('Intensity') == 'Very High') & (f.col('Severity') == 'Medium') , "Orange")
.otherwise('Yellow'))))
.otherwise(f.when((f.col('Intensity') == 'High') & (f.col('Severity') == 'Very High') , "Red").
otherwise(f.when((f.col('Intensity') == 'High') & (f.col('Severity') == 'High') , "Orange").
otherwise(f.when((f.col('Intensity') == 'High') & (f.col('Severity') == 'Medium') , "Orange")
.otherwise('Yellow'))))
.otherwise(f.when((f.col('Intensity') == 'Medium') & (f.col('Severity') == 'Very High') , "Orange").
otherwise(f.when((f.col('Intensity') == 'Medium') & (f.col('Severity') == 'High') , "Yellow").
otherwise(f.when((f.col('Intensity') == 'Medium') & (f.col('Severity') == 'Medium') , "Yellow")
.otherwise('Green'))))
.otherwise(f.when((f.col('Intensity') == 'Low') & (f.col('Severity') == 'Very High') , "Yellow").
otherwise(f.when((f.col('Intensity') == 'Low') & (f.col('Severity') == 'High') , "Green").
otherwise(f.when((f.col('Intensity') == 'Low') & (f.col('Severity') == 'Medium') , "Green")
.otherwise('Green'))))
).otherwise("")
But , I got this Error :
A Tuple Object dosen't have an attribute Otherwise
Any help would be much appreciated , thank you
just to give an example of what #jxc meant:
Assuming you already have a dataframe called df:
from pyspark.sql.functions import expr
Intensities = df.withColumn('Intensities', expr("CASE WHEN Intensity = 'Very High' AND Severity = 'Very High' THEN 'Red' WHEN .... ELSE ... END"))
I put "..." in as placeholder, but I think it makes the approach clear.

Django REST Framework: custom serializer variables

I am using a model serializer (many=True) in Django Rest Framework where I want to return booking_color and text_color properties in JSON in order to display a booking instance on a calendar plugin. Both properties depend on job_type and job_status variables that are calculated (using foreign keys, etc.). I want to run a calculation for those variables when a particular instance gets initialized (in the init method) so that both calculated values then become available for both method fields (booking_color and text_color). The init method, however, passes entire queryset as 'inst' and so I can't do instance-specific calculations. What would be the best way around this? I have previously ran those calculations in the first method in the list ('get_booking_color' in this case) and it works, but it isn't very elegant and I am not sure if I am supposed to do it.
class CalendarView(serializers.ModelSerializer):
booking_color = serializers.SerializerMethodField()
text_color = serializers.SerializerMethodField()
def __init__(self, inst):
self.job_type = [complicated calculation that depends on inst values]
self.invoice_status = [complicated calculation that depends on inst values]
def get_booking_color(self, inst):
if self.invoice_status == 1:
if self.job_type == 1:
return "#000000"
elif self.job_type == 2:
return "#f1c40f"
elif self.job_type == 3:
return "#FFFFF"
else:
return '#faase4'
def get_text_color(self, inst):
if self.invoice_status == 2:
if self.job_type == 1:
return "#BBFF33"
elif self.job_type == 2:
return "#272844"
elif self.job_type == 3:
return "#2c0716"
else:
return '#FFFFF'
I believe you need to modify your __init__() call to this:
def __init__(self, instance=None, data=empty, **kwargs):
self.job_type = [complicated calculation that depends on inst values]
self.invoice_status = [complicated calculation that depends on inst values]
super(CalendarViewSerializer, self).__init__(**kwargs)
I'd also recommend renaming your class to CalendarViewSerializer so it is not confused with anythign else.
You may also be able to move around overriding the __init__() call by passing in those calculations via the context - then working with them from there...e.g.,
serializer = CalendarViewSerializer(data=request.data, context={'job_type': ..., 'invoice_status': ...})
class CalendarViewSerializer(serializers.ModelSerializer):
booking_color = serializers.SerializerMethodField()
text_color = serializers.SerializerMethodField()
def get_booking_color(self, inst):
if self.context['invoice_status'] == 1:
if self.context['job_type'] == 1:
return "#000"
elif self.context['job_type'] == 2:
return "#f1c40f"
elif self.context['job_type'] == 3:
return "#fff"
else:
return '#faase4'
def get_text_color(self, inst):
if self.context['invoice_status'] == 2:
if self.context['job_type'] == 1:
return "#bbff33"
elif self.context['job_type'] == 2:
return "#272844"
elif self.context['job_type'] == 3:
return "#2c0716"
else:
return '#fff'
As an extra bonus, I believe you could use some sort of dict()/{} object to return the hex codes from a key lookup, rather than the if elseif elseif else statements.

Cascading Multiple conditions with if status, to create 2 categorical columns

Well
It was been like half an hour writting and rewritting this with no success:
Hope any caritative soul can help me with some wisdom
Heres the two pieces of code I have tried, the most basic ones I tried before did not work also:
I am triying to make 2 columns with this if else conditional, I cant really figure out whats going on...
vel_sign = []
ac_sign = []
for i in range(len(X_train)):
if (int(X_train['Velocidad'][i]) > 0) and (int(X_train['Aceleracion'][i]) > 0):
vel_sign.append(1)
ac_sign.append(1)
elif (int(X_train['Velocidad'][i]) > 0) and (int(X_train['Aceleracion'][i]) == 0):
vel_sign.append(1)
ac_sign.append(0)
elif (int(X_train['Velocidad'][i]) > 0) and (int(X_train['Aceleracion'][i]) < 0):
vel_sign.append(1)
ac_sign.append(-1)
else: pass
vel_sign = []
ac_sign = []
for i in range(len(X_train)):(
if (X_train['Velocidad'][i] > 0):
vel_sign.append(1)
if (X_train['Aceleracion'][i] > 0):
ac_sign.append(1)
elif (X_train['Aceleracion'][i] == 0):
ac_sign.append(0)
elif (X_train['Aceleracion'][i] < 0):
ac_sign.append(-1)
else:pass
elif (X_train['Velocidad'][i] == 0):
vel_sign.append(0)
if (X_train['Aceleracion'][i] > 0):
ac_sign.append(1)
elif (X_train['Aceleracion'][i] == 0):
ac_sign.append(0)
elif (X_train['Aceleracion'][i] < 0):
ac_sign.append(-1)
else: pass
elif (X_train['Velocidad'][i] < 0):
vel_sign.append(-1)
if (X_train['Aceleracion'][i] > 0):
ac_sign.append(1)
elif (X_train['Aceleracion'][i] == 0):
ac_sign.append(0)
elif (X_train['Aceleracion'][i] < 0):
ac_sign.append(-1)
else: pass
else: pass)
X_train['V_signo'] = vel_sign
X_train['A_signo'] = ac_sign
print(X_train.head())
The error is the following
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-39-d5c1cf0b654a> in <module>
2 ac_sign = []
3 for i in range(len(X_train)):
----> 4 if (int(X_train['Velocidad'][i]) > 0) and (int(X_train['Aceleracion'][i]) > 0):
5 vel_sign.append(1)
6 ac_sign.append(1)
/opt/conda/lib/python3.6/site-packages/pandas/core/series.py in __getitem__(self, key)
1069 key = com.apply_if_callable(key, self)
1070 try:
-> 1071 result = self.index.get_value(self, key)
1072
1073 if not is_scalar(result):
/opt/conda/lib/python3.6/site-packages/pandas/core/indexes/base.py in get_value(self, series, key)
4728 k = self._convert_scalar_indexer(k, kind="getitem")
4729 try:
-> 4730 return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None))
4731 except KeyError as e1:
4732 if len(self) > 0 and (self.holds_integer() or self.is_boolean()):
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()
KeyError: 3
THANKS!!!!!!!!!!!!!
I think I got an Answer,
But if anyone got a better one, I would like to hear it :D:D
def Signo(array):
result = []
for x in range(len(array)):
if array[x] > 0:
result.append(1)
elif array[x] == 0:
result.append(0)
else:
result.append(-1)
return result
df['Vel_signo'] = Signo(df['Velocidad'].to_numpy())
df['Ac_signo'] = Signo(df['Aceleracion'].to_numpy())

Python: list comparison vs integer comparison which is more efficient?

I am currently implementing the LTE physical layer in Python (ver 2.7.7).
For the qpsk, 16qam and 64qam modulation I would like to know which is more efficient to use between an integer comparison and a list comparison:
Integer comparison: bit_pair as an integer value before comparison
# QPSK - TS 36.211 V12.2.0, section 7.1.2, Table 7.1.2-1
def mp_qpsk(self):
r = []
for i in range(self.nbits/2):
bit_pair = (self.sbits[i*2] << 1) | self.sbits[i*2+1]
if bit_pair == 0:
r.append(complex(1/math.sqrt(2),1/math.sqrt(2)))
elif bit_pair == 1:
r.append(complex(1/math.sqrt(2),-1/math.sqrt(2)))
elif bit_pair == 2:
r.append(complex(-1/math.sqrt(2),1/math.sqrt(2)))
elif bit_pair == 3:
r.append(complex(-1/math.sqrt(2),-1/math.sqrt(2)))
return r
List comparison: bit_pair as a list before comparison
# QPSK - TS 36.211 V12.2.0, section 7.1.2, Table 7.1.2-1
def mp_qpsk(self):
r = []
for i in range(self.nbits/2):
bit_pair = self.sbits[i*2:i*2+2]
if bit_pair == [0,0]:
r.append(complex(1/math.sqrt(2),1/math.sqrt(2)))
elif bit_pair == [0,1]:
r.append(complex(1/math.sqrt(2),-1/math.sqrt(2)))
elif bit_pair == [1,0]:
r.append(complex(-1/math.sqrt(2),1/math.sqrt(2)))
elif bit_pair == [1,1]:
r.append(complex(-1/math.sqrt(2),-1/math.sqrt(2)))
return r
Thanks

Tic-Tac-Toe TypeError: 'NoneType' object has no attribute '__getitem__'

I am programming a Tic-Tac-Toe game. I have most of the program done. But I keep getting the following error and I don't understand what I am doing wrong. I have tried formatting it differently.
Traceback (most recent call last):
File "C:/Users/Akshay Sastry/Documents/CS 303E/Tic-Tac-Toe.py", line 66, in <module>
main()
File "C:/Users/Akshay Sastry/Documents/CS 303E/Tic-Tac-Toe.py", line 3, in main
while isWinner(board) == 0 and movesLeft(board) == True:
File "C:/Users/Akshay Sastry/Documents/CS 303E/Tic-Tac-Toe.py", line 20, in isWinner
if (b[0][0]=='x') and (b[0][0]==b[0][1]==b[0][2]):
TypeError: 'NoneType' object has no attribute '__getitem__'
This is my code:
def main():
board = makeBoard()
while isWinner(board) == 0 and movesLeft(board) == True:
printBoard(board)
p1row, p1col = input("Enter a row and column for x: ")
board[p1row][p1col] = 'x'
if isWinner(board) == 0 and movesLeft(board) == True:
printBoard(board)
p2row, p2col = input("Enter a row and column for o: ")
board[p2row][p2col] = 'o'
if isWinner(board) != 0:
print isWinner(board), 'won!'
else:
print 'Tie game.'
def makeBoard():
board = [['*','*','*'],['*','*','*'],['*','*','*']]
def isWinner(b):
if (b[0][0]=='x') and (b[0][0]==b[0][1]==b[0][2]):
return 'x'
elif (b[1][0]=='x') and (b[1][0]==b[1][1]==b[1][2]):
return 'x'
elif (b[2][0]=='x') and (b[2][0]==b[1][1]==b[2][2]):
return 'x'
elif (b[0][0]=='x') and (b[0][0]==b[1][0]==b[2][0]):
return 'x'
elif (b[0][1]=='x') and (b[0][1]==b[1][1]==b[2][1]):
return 'x'
elif (b[0][2]=='x') and (b[0][2]==b[1][2]==b[2][2]):
return 'x'
elif (b[0][0]=='x') and (b[0][0]==b[1][1]==b[2][2]):
return 'x'
elif (b[0][2]=='x') and (b[0][2]==b[1][1]==b[2][0]):
return 'x'
elif (b[0][0]=='o') and (b[0][0]==b[0][1]==b[0][2]):
return 'o'
elif (b[1][0]=='o') and (b[1][0]==b[1][1]==b[1][2]):
return 'o'
elif (b[2][0]=='o') and (b[2][0]==b[1][1]==b[2][2]):
return 'o'
elif (b[0][0]=='o') and (b[0][0]==b[1][0]==b[2][0]):
return 'o'
elif (b[0][1]=='o') and (b[0][1]==b[1][1]==b[2][1]):
return 'o'
elif (b[0][2]=='o') and (b[0][2]==b[1][2]==b[2][2]):
return 'o'
elif (b[0][0]=='o') and (b[0][0]==b[1][1]==b[2][2]):
return 'o'
elif (b[0][2]=='o') and (b[0][2]==b[1][1]==b[2][0]):
return 'o'
else:
return 0
def printBoard(board):
for i in range(3):
for j in range(3):
print board[i][j],
print
def movesLeft(board):
if board[0].count("*") != 0 or board[1].count("*") != 0 or board[2].count("*") != 0:
return True
else:
return False
main()
Your makeBoard() function returns None. You should make it like this:
def makeBoard():
return [['*','*','*'],['*','*','*'],['*','*','*']]
Your isWinner function can be made 3x smaller, as follows
def isWinner(b):
for i in range(3):
if (b[i][0] != '*') and (b[i][0]==b[i][1]==b[i][2]): # all rows
return b[i][0]
if (b[0][i] != '*') and (b[0][i]==b[1][i]==b[2][i]): # all cols
return b[0][i]
if (b[0][0] != '*') and (b[0][0]==b[1][1]==b[2][2]): # tl-br diag
return b[0][0]
elif (b[0][2] != '*') and (b[0][2]==b[1][1]==b[2][0]): # bl-tr diag
return b[0][2]
else:
return 0
For a larger board such as connect 4, however, you'd iterate over all points on the board and write a method that checked in a loop an arbitrary distance in every direction, rather than hard-coding every place a row can be in.