How do I condense the loop and if else - python

Is there a better or shorter way to write this code?
def business_role_code_to_name(x):
y = []
for position, code in enumerate(x):
if position == 0 and code == 1.0:
y.append("Owner")
elif position == 1 and code == 1.0:
y.append("Manager")
elif position == 2 and code == 1.0:
y.append("Employee")
elif position == 3 and code == 1.0:
y.append("Other")
return y
assert business_role_code_to_name([1.0, 1.0, 1.0, 0.0]) == ['Owner', 'Manager', 'Employee']
assert business_role_code_to_name([0.0, 1.0, 0.0, 1.0]) == ['Manager', 'Other']
I am new to programming, I think there is a better way to write this code. Thanks!

Try using:
def business_role_code_to_name(x):
y = []
d = {(0, 1): 'Owner', (1, 1): 'Manager', (2, 1): 'Employee', (3, 1): 'Other'}
for i in enumerate(x):
if d.get(i):
y.append(d[i])
return y

Use itertools.compress:
from itertools import compress
names = ['Owner', 'Manager', 'Employee', 'Other']
positions_0 = [1.0, 1.0, 1.0, 0.0]
positions_1 = [0.0, 1.0, 0.0, 1.0]
Output:
list(compress(names, positions_0))
# ['Owner', 'Manager', 'Employee']
list(compress(names, positions_1))
# ['Manager', 'Other']

The function business_role_code_to_name has the same logic as below
def business_role_code_to_name(x):
z = ['Owner', 'Manager', 'Employee' ,'Other']
y = [z[position] for position, code in enumerate(x) if code==1.0]
return y

You might use zip for that task following way:
roles = ["Owner","Manager","Employee","Other"]
code1 = [1.0, 1.0, 1.0, 0.0]
code2 = [0.0, 1.0, 0.0, 1.0]
def decode_role(rolecode):
return [role for code,role in zip(rolecode,roles) if code==1.0]
print(decode_role(code1)) # ['Owner', 'Manager', 'Employee']
print(decode_role(code2)) # ['Manager', 'Other']

I have written an example with error handling:
Function:
def business_role_code_to_name(x):
y = []
positions = {0: "Owner", 1: "Manager", 2: "Employee", 3: "Other"}
for position, code in enumerate(x):
if code != 1.0:
continue
try:
y.append(positions[position])
except KeyError as key_err:
print("{} is a wrong index.".format(position))
raise key_err
return y
Test:
print(business_role_code_to_name([1.0, 1.0, 1.0, 0.0]))
print(business_role_code_to_name([0.0, 1.0, 0.0, 1.0]))
print(business_role_code_to_name([0.0, 1.0, 0.0, 1.0, 1.0]))
Output:
>>> python3 test.py
['Owner', 'Manager', 'Employee']
['Manager', 'Other']
4 is a wrong index.
Traceback (most recent call last):
File "test.py", line 21, in <module>
print(business_role_code_to_name([0.0, 1.0, 0.0, 1.0, 1.0]))
File "test.py", line 11, in business_role_code_to_name
raise key_err
File "test.py", line 8, in business_role_code_to_name
y.append(positions[position])
KeyError: 4

You can do it like this without foor loops:
roles = ('Owner', 'Manager', 'Employee', 'Other')
def business_role_code_to_name(x):
positions = filter(lambda k: x[k] == 1.0, range(len(x)))
return list(map(roles.__getitem__, positions))

Related

Jupyter Notebook not updating with ipywidget change

When I update my widgets nothing happens.
I am trying to display a bar chart and select the data based on widgets inputs.
I have a small dataframe of 600 rows. Each row is has M atk_dice, N def_dice, and atk_tl bool, and a few other selectors. The data is a variable length list, which will be a bar chart of the probability distribution function.
import plotly.graph_objects as go
import pandas as pd
import numpy as np
from ipywidgets import widgets
atk_dice = widgets.IntSlider(
value = 1.0,
min = 1.0,
max = 6.0,
step = 1.0,
description = 'Number of Attack Dice',
continuous_update = False)
def_dice = widgets.IntSlider(
value = 1.0,
min = 1.0,
max = 6.0,
step = 1.0,
description = 'Number of Defense Dice',
continuous_update = False)
tgt_lk = widgets.Checkbox(
description = 'Target Lock',
value = False)
container = widgets.HBox(children = [atk_dice, def_dice, tgt_lk])
j = 1
row = df.iloc[j]
M = (row['M_atk_dice'])
mPhr = row.Phr
mhits = np.arange(M+1)
trace1 = go.Bar(x = mhits, y = mPhr, opacity= 0.8, name = 'pdf')
g = go.FigureWidget(data = [trace1],
layout = go.Layout(
title = dict(text = 'PDF')
)
)
def response(change):
M = 10
x1 = np.arange(M+1)
y1 = x1
with g.batch_update():
g.data[0].x = x1
g.data[0].y = y1
atk_dice.observe(response, names = "All", type = "change")
def_dice.observe(response, names = "All", type = "change")
tgt_lk.observe(response, names = "All", type = "change")
widgets.VBox([container, g])
Thanks in advance.
When you're building up these functions and interacts I always try to start with a basic print function. Having name='All' in your observe call isn't correct, none of the dict keys match name=All so your function isn't being run. Look at the names and types that occur from a slider without any kwargs in the observe call:
import pandas as pd
import numpy as np
from ipywidgets import widgets
atk_dice = widgets.IntSlider(
value = 1.0,
min = 1.0,
max = 6.0,
step = 1.0,
description = 'Number of Attack Dice',
continuous_update = False)
def response(change):
print(change)
atk_dice.observe(response)
atk_dice
{'name': '_property_lock', 'old': traitlets.Undefined, 'new': {'value': 2}, 'owner': IntSlider(value=1, continuous_update=False, description='Number of Attack Dice', max=6, min=1), 'type': 'change'}
{'name': 'value', 'old': 1, 'new': 2, 'owner': IntSlider(value=2, continuous_update=False, description='Number of Attack Dice', max=6, min=1), 'type': 'change'}
{'name': '_property_lock', 'old': {'value': 2}, 'new': {}, 'owner': IntSlider(value=2, continuous_update=False, description='Number of Attack Dice', max=6, min=1), 'type': 'change'}
You probably want atk_dice.observe(response, names = "value", type = "change").

Linear programming two sets of constraints CPLEX Python API

I am trying to solve a linear programming problem using IBM's CPLEX Python API. It involves two sets of equality constraints. The code below works fine when we use either one of the two sets of constraints, but fails to find a solution when both sets of constraints are used.
The constraints are:
First constraint: Wx' = c', where W = [[20,0,0],[0,20,30]], x = [a,b,c], c=[20,30]
Second constraint: Vx' = e', where V = [[1,1,0],[0,0,1]], x = [a,b,c], c=[1,1]
Objective function: minimize a + c
One solution which meets both sets of constrains is a=1, b=0, c=1.
There is an error in the way I am introducing the two sets of constrains in Cplex Python. My code is below. To check that the code works with either set of constraints by itself comment out on of the sets of constraints.
import cplex
from cplex.exceptions import CplexError
import sys
def populatebynonzero(prob):
my_obj = [1.0, 0.0, 1.0]
my_ub = [1.0] * len(my_obj)
my_lb = [0.0] * len(my_obj)
my_colnames = ["a", "b", "c"]
prob.objective.set_sense(prob.objective.sense.minimize)
prob.variables.add(obj = my_obj, ub = my_ub, lb = my_lb ,names = my_colnames)
# first set of equality constraints: Wx' = c', where W = [[20,0,0],[0,20,30]], x = [a,b,c], c=[20,30]
my_rhs = [20.0, 30.0]
my_rownames = ["c1", "c2"]
my_sense = "E" * len(my_rownames)
rows = [0,1,1]
cols = [0,1,2]
vals = [20.0,20.0,30.0]
prob.linear_constraints.add(rhs = my_rhs, senses = my_sense,names = my_rownames)
prob.linear_constraints.set_coefficients(zip(rows, cols, vals))
# second set of equality constraints: Vx' = e', where V = [[1,1,0],[0,0,1]], x = [a,b,c], c=[1,1]
my_rhs = [1.0, 1.0]
my_rownames = ["e1", "e2"]
my_sense = "E" * len(my_rownames)
rows = [0,0,1]
cols = [0,1,2]
vals = [1.0,1.0,1.0]
prob.linear_constraints.add(rhs = my_rhs, senses = my_sense,names = my_rownames)
prob.linear_constraints.set_coefficients(zip(rows, cols, vals))
def lpex1():
try:
my_prob = cplex.Cplex()
handle = populatebynonzero(my_prob)
my_prob.solve()
except CplexError, exc:
print exc
return
numrows = my_prob.linear_constraints.get_num()
numcols = my_prob.variables.get_num()
print
# solution.get_status() returns an integer code
print "Solution status = " , my_prob.solution.get_status(), ":",
# the following line prints the corresponding string
print my_prob.solution.status[my_prob.solution.get_status()]
print "Solution value = ", my_prob.solution.get_objective_value()
slack = my_prob.solution.get_linear_slacks()
pi = my_prob.solution.get_dual_values()
x = my_prob.solution.get_values()
dj = my_prob.solution.get_reduced_costs()
for i in range(numrows):
print "Row %d: Slack = %10f Pi = %10f" % (i, slack[i], pi[i])
for j in range(numcols):
print "Column %d: Value = %10f Reduced cost = %10f" % (j, x[j], dj[j])
my_prob.write("lpex1.lp")
print x, "SOLUTIONS"
lpex1()
It works if the two sets of constraints are combined into one matrix in the following way, though it would be good to find a solution which does not have to do combining
import cplex
from cplex.exceptions import CplexError
import sys
def populatebynonzero(prob):
my_obj = [1.0, 0.0, 1.0]
my_ub = [1.0] * len(my_obj)
my_lb = [0.0] * len(my_obj)
my_colnames = ["a", "b", "c"]
prob.objective.set_sense(prob.objective.sense.minimize)
prob.variables.add(obj = my_obj, ub = my_ub, lb = my_lb ,names = my_colnames)
#combined constraints
my_rhs = [20.0, 30.0, 1.0, 1.0]
my_rownames = ["c1", "c2", "e1", "e2"]
my_sense = "E" * len(my_rownames)
rows = [0,1,1,2,2,3]
cols = [0,1,2,0,1,2]
vals = [20.0,20.0,30.0,1,1,1]
prob.linear_constraints.add(rhs = my_rhs, senses = my_sense,names = my_rownames)
prob.linear_constraints.set_coefficients(zip(rows, cols, vals))
"""
# first set of equality constraints: Wx' = c', where W = [[20,0,0],[0,20,30]], x = [a,b,c], c=[20,30]
my_rhs = [20.0, 30.0]
my_rownames = ["c1", "c2"]
my_sense = "E" * len(my_rownames)
rows = [0,1,1]
cols = [0,1,2]
vals = [20.0,20.0,30.0]
prob.linear_constraints.add(rhs = my_rhs, senses = my_sense,names = my_rownames)
prob.linear_constraints.set_coefficients(zip(rows, cols, vals))
# second set of equality constraints: Vx' = e', where V = [[1,1,0],[0,0,1]], x = [a,b,c], c=[1,1]
my_rhs = [1.0, 1.0]
my_rownames = ["e1", "e2"]
my_sense = "E" * len(my_rownames)
rows = [0,0,1]
cols = [0,1,2]
vals = [1.0,1.0,1.0]
prob.linear_constraints.add(rhs = my_rhs, senses = my_sense,names = my_rownames)
prob.linear_constraints.set_coefficients(zip(rows, cols, vals))
"""
def lpex1():
try:
my_prob = cplex.Cplex()
handle = populatebynonzero(my_prob)
my_prob.solve()
except CplexError, exc:
print exc
return
numrows = my_prob.linear_constraints.get_num()
numcols = my_prob.variables.get_num()
print
# solution.get_status() returns an integer code
print "Solution status = " , my_prob.solution.get_status(), ":",
# the following line prints the corresponding string
print my_prob.solution.status[my_prob.solution.get_status()]
print "Solution value = ", my_prob.solution.get_objective_value()
slack = my_prob.solution.get_linear_slacks()
pi = my_prob.solution.get_dual_values()
x = my_prob.solution.get_values()
dj = my_prob.solution.get_reduced_costs()
for i in range(numrows):
print "Row %d: Slack = %10f Pi = %10f" % (i, slack[i], pi[i])
for j in range(numcols):
print "Column %d: Value = %10f Reduced cost = %10f" % (j, x[j], dj[j])
my_prob.write("lpex1.lp")
print x, "SOLUTIONS"
lpex1()
When you are attempting to create the second set of constraints, you are using the wrong indices for the rows:
# second set of equality constraints: Vx' = e', where V = [[1,1,0],[0,0,1]], x = [a,b,c], c=[1,1]
my_rhs = [1.0, 1.0]
my_rownames = ["e1", "e2"]
my_sense = "E" * len(my_rownames)
rows = [0,0,1] # <- HERE
cols = [0,1,2]
vals = [1.0,1.0,1.0]
That is, you're using the row indices 0 and 1, which were created for the first set of constraints. Instead, you should do something like the following:
# second set of equality constraints: Vx' = e', where V = [[1,1,0],[0,0,1]], x = [a,b,c], c=[1,1]
my_rhs = [1.0, 1.0]
my_rownames = ["e1", "e2"]
my_sense = "E" * len(my_rownames)
cols = [0,1,2]
vals = [1.0,1.0,1.0]
rowindices = list(prob.linear_constraints.add(rhs = my_rhs, senses = my_sense,names = my_rownames))
assert len(rowindices) == 2
rows = [rowindices[0], rowindices[0], rowindices[1]]
prob.linear_constraints.set_coefficients(zip(rowindices, cols, vals))
Above, we get the new row indices from the call to prob.linear_constriants.add. With this change, the script works fine.
In addition, it's a good idea to write out the problem in LP format to make sure that it looks correct, like so:
prob.write("model.lp")

Fuzzy rules with more than two input variables in python

I am trying to build a fuzzy inference system in python. I have 4 variables depending on which output class is decided.
def fuzzInferenceself():
### Input ###
hf_very_poor = fuzz.trimf(hotel_facility, [0, 0.15, 0.3])
hf_poor = fuzz.trimf(hotel_facility, [2.5,0.3,0.45])
hf_average = fuzz.trimf(hotel_facility, [0.4, 0.5, 0.75])
hf_good = fuzz.trimf(hotel_facility, [0.7, 0.85, 0.9])
hf_very_good = fuzz.trimf(hotel_facility, [0.875, 0.92, 1.0])
vc_less = fuzz.trimf(visited_count, [0, 0.05, 0.1])
vc_average = fuzz.trimf(visited_count, [0.05, 0.2, 0.35])
vc_many = fuzz.trapmf(visited_count, [0.3,0.45,0.55,0.7])
vc_a_lot = fuzz.trapmf(visited_count, [0.65,0.8,0.9,1.0])
rm_very_poor = fuzz.trimf(hotel_facility, [0, 0.15, 0.3])
rm_poor = fuzz.trimf(hotel_facility, [2.5,0.3,0.45])
rm_average = fuzz.trimf(hotel_facility, [0.4, 0.5, 0.75])
rm_good = fuzz.trimf(hotel_facility, [0.7, 0.8, 0.9])
rm_very_good = fuzz.trimf(hotel_facility, [0.85, 0.9,1.0])
## output ####
class_very_poor = fuzz.gaussmf(class_score,1,0.5)
class_poor = fuzz.gaussmf(class_score,1.75,0.65)
class_average = fuzz.gaussmf(class_score,2.25,0.75)
class_good = fuzz.gaussmf(class_score,3,0.25)
class_very_good = fuzz.gaussmf(class_score, 3.5, 0.5)
def hotelFaclilityClassification(self,A):
hf_vp= fuzz.interp_membership(hotel_facility, hf_very_poor, A)
hf_p= fuzz.interp_membership(hotel_facility, hf_poor, A)
hf_av= fuzz.interp_membership(hotel_facility, hf_average, A)
hf_gd= fuzz.interp_membership(hotel_facility, hf_good, A)
hf_vg= fuzz.interp_membership(hotel_facility, hf_very_good, A)
return dict(hfVP = hf_vp, hfP = hf_p, hfAV = hf_av,hGD = hf_gd, hVG = hf_vg)
def visitCountClassification(B):
vc_l = fuzz.interp_membership(visited_count,vc_less)
vc_av = fuzz.interp_membership(visited_count,vc_average)
vc_mn = fuzz.interp_membership(visited_count,vc_many)
vc_al = fuzz.interp_membership(visited_count,vc_a_lot)
return dict(vcL = vc_l, vcAV=vc_av, vcMN = vc_mn, vcAL = vc_al )
def roomFacilityClassification(C):
rm_vp = fuzz.interp_membership(room_facility,rm_very_poor)
rm_p = fuzz.interp_membership(room_facility,rm_poor)
rm_av = fuzz.interp_membership(room_facility,rm_average)
rm_gd = fuzz.interp_membership(room_facility,rm_good)
rm_vg = fuzz.interp_membership(room_facility,rm_very_good)
return dict(rmVP = rm_vp, rmP = rm_p, rmAV = rm_av, rmGD = rm_gd, rmVG = rm_vg)
A similar function for price is: def priceClassification(D).
The rules are as follows:
"If Hotel facility score is Very good, visited count is alot, room facility is very good,prices is less then class is very good."
I do not understand how to code the rules. All sources I have seen takes one input and one output variable. But this is not the case in my code.
Can anyone give me a good resource or idea about how to code this rule?

python uppercase and ascii in persian text

I change this code to work in persian. My code returns:
Key: Text is too short to analyze Text:
and doesn't return key and decrypt text. Is it anything wrong with uppercase or ascii in persian text? What can I do?
# -*- coding: utf-8 -*-
from string import uppercase
from operator import itemgetter
def vigenere_decrypt(target_freqs, input):
nchars = len(uppercase)
ordA = ord(u"ا")
sorted_targets = sorted(target_freqs)
def frequency(input):
result = [[c, 0.0] for c in uppercase]
for c in input:
result[c - ordA][1] += 1
return result
def correlation(input):
result = 0.0
freq = frequency(input)
freq.sort(key=itemgetter(1))
for i, f in enumerate(freq):
result += f[1] * sorted_targets[i]
return result
cleaned = [ord(c) for c in input.upper() if c.isupper()]
best_len = 0
best_corr = -100.0
# Assume that if there are less than 20 characters
# per column, the key's too long to guess
for i in xrange(2, len(cleaned) // 20):
pieces = [[] for _ in xrange(i)]
for j, c in enumerate(cleaned):
pieces[j % i].append(c)
# The correlation seems to increase for smaller
# pieces/longer keys, so weigh against them a little
corr = -0.5 * i + sum(correlation(p) for p in pieces)
if corr > best_corr:
best_len = i
best_corr = corr
if best_len == 0:
return ("Text is too short to analyze", "")
pieces = [[] for _ in xrange(best_len)]
for i, c in enumerate(cleaned):
pieces[i % best_len].append(c)
freqs = [frequency(p) for p in pieces]
key = ""
for fr in freqs:
fr.sort(key=itemgetter(1), reverse=True)
m = 0
max_corr = 0.0
for j in xrange(nchars):
corr = 0.0
c = ordA + j
for frc in fr:
d = (ord(frc[0]) - c + nchars) % nchars
corr += frc[1] * target_freqs[d]
if corr > max_corr:
m = j
max_corr = corr
key += chr(m + ordA)
r = (chr((c - ord(key[i % best_len]) + nchars) % nchars + ordA)
for i, c in enumerate(cleaned))
return (key, "".join(r))
def main():
encoded = " پهيتش غعهدد ذصلدي هزفضر کنهرظ ضذکاح يصتمد "
english_frequences = [
14, 4.2, 0.7, 5.2, 0.1, 1.2, 0.4,
1, 1.4, 7.5, 0.1, 8.5, 2.1, 0.1,
3.3, 2.6, 0.7, 0.3, 0.6, 0.2, 1.5,
0.2, 1.6, 1.2, 3, 1.7, 2.7, 5.7, 7.1, 6, 5.7, 9.1]
(key, decoded) = vigenere_decrypt(english_frequences, encoded)
print "Key:", key
print "\nText:", decoded
main()

how to get the formatted output

Hi i'm using the python and odbc database i.e Microsoft access. I'm getting the output like
(u'EXPANDx TB', 12.0, 10.0, 11.0, 13.0, 0.0, 46.0)
(u'EXPANDx TB & GFATM', 1.0, 1.0, 0.0, 1.0, 0.0, 3.0)
(u'EXPANDx TB & NRHM', 0.0, 0.0, 1.0, 0.0, 0.0, 1.0)
(u'GFATM', 1.0, 1.0, 0.0, 0.0, 0.0, 2.0)
(u'WHO', 3.0, 7.0, 3.0, 5.0, 0.0, 18.0)
(u'GFATM & EXPANDx TB', 1.0, 0.0, 0.0, 0.0, 0.0, 1.0)
the extra term "u" is displaying. I also used the join function but getting the error like
print ",".join(table1)
TypeError: sequence item 1: expected string or Unicode, float found
please help me out with this. Thanks in advance.
#!/usr/bin/python
import pyodbc
db_file = r'''C:\Users\Basavaraj\Documents\C&DST.accdb'''
user = ''
password = ''
odbc_conn_str = 'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=%s;UID=%s;PWD=%s' % \
(db_file, user, password)
conn= pyodbc.connect(odbc_conn_str)
#for row in cursor.fetchall():
# print row[2]
try:
cursor = conn.cursor()
cursor.execute("select * from Table1")
for table1 in cursor.fetchall():
print ",".join(table1)
finally:
conn.close()
`
Just convert each item to string.
print ",".join(str(i) for i in table1)
If you want to keep the unicode items as is, then :
print ",".join(str(i) if not isinstance(i, unicode) else i for i in table1)

Categories