Commit 7742f981 authored by Jérome Perrin's avatar Jérome Perrin

modify InputData_DemandPlanning to have a function that we can call externally

parent 6ca25d01
...@@ -23,59 +23,68 @@ Created on 7 May 2014 ...@@ -23,59 +23,68 @@ Created on 7 May 2014
@author: Panos @author: Panos
''' '''
from DistributionFitting import Distributions from dream.KnowledgeExtraction.DistributionFitting import Distributions
from ImportExceldata import Import_Excel from dream.KnowledgeExtraction.ImportExceldata import Import_Excel
from ReplaceMissingValues import HandleMissingValues from dream.KnowledgeExtraction.ReplaceMissingValues import HandleMissingValues
import rpy2.robjects as robjects import rpy2.robjects as robjects
from xlwt import Workbook from xlwt import Workbook
import json import json
import xlrd import xlrd
import random import random
import urllib
#Read data from the exported Excel file from RapidMiner and call the Import_Excel object of the KE tool to import this data in the tool def generateDemandPlanning(input_url):
workbook = xlrd.open_workbook(r'Input8PPOS.xlsx','r') """Generate random demand from spreadsheet at input_url.
worksheets = workbook.sheet_names() """
worksheet_RapidMiner = worksheets[0]
PPOSToBeDisaggregated='PPOS4' # Read data from the exported Excel file from RapidMiner and call the Import_Excel object of the KE tool to import this data in the tool
PPOSQuantity=1000
PlannedWeek=2 demand_data = urllib.urlopen(input_url).read()
workbook = xlrd.open_workbook(file_contents=demand_data)
A= Import_Excel()
Turnovers=A.Input_data(worksheet_RapidMiner, workbook) #Dictionary with the data from the Excel file worksheets = workbook.sheet_names()
worksheet_RapidMiner = worksheets[0]
#Create lists with the MAs' names and the Turnovers for the first twelve weeks of 2010 retrieving this data from the dictionary
PPOS=Turnovers.get('Ppos',[]) PPOSToBeDisaggregated='PPOS4'
SP=Turnovers.get('SP',[]) PPOSQuantity=1000
MA=Turnovers.get('FP Material No PGS+',[]) PlannedWeek=2
GlobalDemand=Turnovers.get('Global demand',[])
A= Import_Excel()
#Call the Distributions object and fit the data from the list in Normal distribution, so as to have info on Global demand (mean and standard deviation) Turnovers=A.Input_data(worksheet_RapidMiner, workbook) #Dictionary with the data from the Excel file
D=Distributions()
E=HandleMissingValues() #Create lists with the MAs' names and the Turnovers for the first twelve weeks of 2010 retrieving this data from the dictionary
MA=E.DeleteMissingValue(MA) PPOS=Turnovers.get('Ppos',[])
t=D.Normal_distrfit(GlobalDemand) SP=Turnovers.get('SP',[])
avg=t.get('mean') MA=Turnovers.get('FP Material No PGS+',[])
stdev=t.get('stdev') GlobalDemand=Turnovers.get('Global demand',[])
def constrained_sum_sample_pos(n, total): #Call the Distributions object and fit the data from the list in Normal distribution, so as to have info on Global demand (mean and standard deviation)
D=Distributions()
E=HandleMissingValues()
MA=E.DeleteMissingValue(MA)
t=D.Normal_distrfit(GlobalDemand)
avg=t.get('mean')
stdev=t.get('stdev')
def constrained_sum_sample_pos(n, total):
"""Return a randomly chosen list of n positive integers summing to total. """Return a randomly chosen list of n positive integers summing to total.
Each such list is equally likely to occur.""" Each such list is equally likely to occur."""
dividers = sorted(random.sample(xrange(1, total), n - 1)) dividers = sorted(random.sample(xrange(1, total), n - 1))
return [a - b for a, b in zip(dividers + [total], [0] + dividers)] return [a - b for a, b in zip(dividers + [total], [0] + dividers)]
def constrained_sum_sample_nonneg(n, total): def constrained_sum_sample_nonneg(n, total):
"""Return a randomly chosen list of n nonnegative integers summing to total. """Return a randomly chosen list of n nonnegative integers summing to total.
Each such list is equally likely to occur.""" Each such list is equally likely to occur."""
return [x - 1 for x in constrained_sum_sample_pos(n, total + n)] return [x - 1 for x in constrained_sum_sample_pos(n, total + n)]
DemandProfile={} #Create a dictionary DemandProfile={} #Create a dictionary
MinPackagingSize=10 MinPackagingSize=10
week=[1,2,3,4,5,6,7,8,9,10] # list that defines the planning horizon, i.e. 10 weeks week=[1,2,3,4,5,6,7,8,9,10] # list that defines the planning horizon, i.e. 10 weeks
for i in week: for i in week:
Demand=int(abs(random.normalvariate(avg,stdev))) # Generate a random, non-negative, integer number from the Normal distribution Demand=int(abs(random.normalvariate(avg,stdev))) # Generate a random, non-negative, integer number from the Normal distribution
AllocatedPercent=0.8-(0.05*i) # Defines a number starts with 0.8 or 80% and reduced with every iteration at 0.05 or 5% AllocatedPercent=0.8-(0.05*i) # Defines a number starts with 0.8 or 80% and reduced with every iteration at 0.05 or 5%
Remaining_Demand=int((1-AllocatedPercent)*Demand) # Defines the Remaining demand Remaining_Demand=int((1-AllocatedPercent)*Demand) # Defines the Remaining demand
...@@ -95,21 +104,21 @@ for i in week: ...@@ -95,21 +104,21 @@ for i in week:
dicta.update({MA[index]:[TotalUnits,MinUnits]}) # it updates a dictionary with key the different MAs and values the remaining demand and (b[index]*lista[index]) dicta.update({MA[index]:[TotalUnits,MinUnits]}) # it updates a dictionary with key the different MAs and values the remaining demand and (b[index]*lista[index])
DemandProfile.update({i:dicta}) #It updates a dictionary with key the number of each iteration (week) and value the dictionary dicta DemandProfile.update({i:dicta}) #It updates a dictionary with key the number of each iteration (week) and value the dictionary dicta
Table=[] Table=[]
i=0 i=0
for i in range(len(MA)): for i in range(len(MA)):
Table.append([PPOS[i],SP[i],MA[i]]) Table.append([PPOS[i],SP[i],MA[i]])
i+=1 i+=1
uniquePPOS=[] uniquePPOS=[]
for ppos in PPOS: for ppos in PPOS:
if not ppos in uniquePPOS and ppos!='': if not ppos in uniquePPOS and ppos!='':
uniquePPOS.append(ppos) uniquePPOS.append(ppos)
book=Workbook() book=Workbook()
sheet1 = book.add_sheet('Future', cell_overwrite_ok=True) sheet1 = book.add_sheet('Future', cell_overwrite_ok=True)
aggrTable=[] aggrTable=[]
for key in DemandProfile.keys(): for key in DemandProfile.keys():
for elem in DemandProfile[key]: for elem in DemandProfile[key]:
if DemandProfile[key].get(elem)[0]> 0: if DemandProfile[key].get(elem)[0]> 0:
MAkey=elem MAkey=elem
...@@ -119,9 +128,9 @@ for key in DemandProfile.keys(): ...@@ -119,9 +128,9 @@ for key in DemandProfile.keys():
aggrTable.append([MAkey,totalUnits,minUnits,plannedWeek]) aggrTable.append([MAkey,totalUnits,minUnits,plannedWeek])
else: else:
continue continue
t=1 t=1
aggrTable.sort(key=lambda x:x[1], reverse=False) aggrTable.sort(key=lambda x:x[1], reverse=False)
for i in sorted(aggrTable, key= lambda x:int(x[3])): for i in sorted(aggrTable, key= lambda x:int(x[3])):
sheet1.write(0,0,'Order ID') sheet1.write(0,0,'Order ID')
sheet1.write(0,1,'MA ID') sheet1.write(0,1,'MA ID')
sheet1.write(0,2,'Total # Units') sheet1.write(0,2,'Total # Units')
...@@ -132,36 +141,35 @@ for i in sorted(aggrTable, key= lambda x:int(x[3])): ...@@ -132,36 +141,35 @@ for i in sorted(aggrTable, key= lambda x:int(x[3])):
sheet1.write(t,3,i[2]) sheet1.write(t,3,i[2])
sheet1.write(t,4,i[3]) sheet1.write(t,4,i[3])
sheet1.write(t,0,t) sheet1.write(t,0,t)
book.save('DemandProfile.xls')
t+=1 t+=1
# open json file # open json file
futureDemandProfileFile=open('futureDemandProfile.json', mode='w') futureDemandProfileFile=open('futureDemandProfile.json', mode='w')
futureDemandProfile={} futureDemandProfile={}
t=1 t=1
for i in sorted(aggrTable, key= lambda x:int(x[3])): for i in sorted(aggrTable, key= lambda x:int(x[3])):
dicta={'MAID':i[0],'TotalUnits':i[1],'MinUnits':i[2],'PlannedWeek':i[3]} dicta={'MAID':i[0],'TotalUnits':i[1],'MinUnits':i[2],'PlannedWeek':i[3]}
futureDemandProfile[t]=dicta futureDemandProfile[t]=dicta
futureDemandProfileString=json.dumps(futureDemandProfile, indent=5) futureDemandProfileString=json.dumps(futureDemandProfile, indent=5)
t+=1 t+=1
#write json file #write json file
futureDemandProfileFile.write(futureDemandProfileString) futureDemandProfileFile.write(futureDemandProfileString)
###==================================================================================================### ###==================================================================================================###
sheet2 = book.add_sheet('PPOS', cell_overwrite_ok=True) sheet2 = book.add_sheet('PPOS', cell_overwrite_ok=True)
dictPPOS={} dictPPOS={}
dictPPOSMA={} dictPPOSMA={}
for ind in uniquePPOS: for ind in uniquePPOS:
indices=[i for i,j in enumerate(PPOS) if j==ind] indices=[i for i,j in enumerate(PPOS) if j==ind]
mas=[ma for ma in MA if (MA.index(ma) in indices)] mas=[ma for ma in MA if (MA.index(ma) in indices)]
dictPPOSMA.update({ind: mas}) dictPPOSMA.update({ind: mas})
t=1 t=1
for key in dictPPOSMA.keys(): for key in dictPPOSMA.keys():
for elem in dictPPOSMA[key]: for elem in dictPPOSMA[key]:
if key==PPOSToBeDisaggregated: if key==PPOSToBeDisaggregated:
c=constrained_sum_sample_nonneg(len(dictPPOSMA[key]),PPOSQuantity) c=constrained_sum_sample_nonneg(len(dictPPOSMA[key]),PPOSQuantity)
...@@ -178,8 +186,8 @@ for key in dictPPOSMA.keys(): ...@@ -178,8 +186,8 @@ for key in dictPPOSMA.keys():
MinUnits=0 MinUnits=0
dictPPOS.update({dictPPOSMA[key][i]:[TotalUnits,MinUnits]}) dictPPOS.update({dictPPOSMA[key][i]:[TotalUnits,MinUnits]})
t=1 t=1
for i in range(0,len(dictPPOS)): for i in range(0,len(dictPPOS)):
sheet2.write(0,0,'Order ID') sheet2.write(0,0,'Order ID')
sheet2.write(0,1,'MA ID') sheet2.write(0,1,'MA ID')
sheet2.write(0,2,'Total # Units') sheet2.write(0,2,'Total # Units')
...@@ -190,18 +198,29 @@ for i in range(0,len(dictPPOS)): ...@@ -190,18 +198,29 @@ for i in range(0,len(dictPPOS)):
sheet2.write(t,2,dictPPOS[dictPPOSMA[PPOSToBeDisaggregated][i]][0]) sheet2.write(t,2,dictPPOS[dictPPOSMA[PPOSToBeDisaggregated][i]][0])
sheet2.write(t,3,dictPPOS[dictPPOSMA[PPOSToBeDisaggregated][i]][1]) sheet2.write(t,3,dictPPOS[dictPPOSMA[PPOSToBeDisaggregated][i]][1])
sheet2.write(t,4,PlannedWeek) sheet2.write(t,4,PlannedWeek)
book.save('DemandProfile.xls')
t+=1 t+=1
# open json file # open json file
PPOSProfileFile=open('PPOSProfile.json', mode='w') PPOSProfileFile=open('PPOSProfile.json', mode='w')
PPOSProfile={} PPOSProfile={}
t=1 t=1
for i in range(0,len(dictPPOS)): for i in range(0,len(dictPPOS)):
dictb={'MAID':dictPPOSMA[PPOSToBeDisaggregated][i],'TotalUnits':dictPPOS[dictPPOSMA[PPOSToBeDisaggregated][i]][0],'MinUnits':dictPPOS[dictPPOSMA[PPOSToBeDisaggregated][i]][1],'PlannedWeek':PlannedWeek} dictb={'MAID':dictPPOSMA[PPOSToBeDisaggregated][i],'TotalUnits':dictPPOS[dictPPOSMA[PPOSToBeDisaggregated][i]][0],'MinUnits':dictPPOS[dictPPOSMA[PPOSToBeDisaggregated][i]][1],'PlannedWeek':PlannedWeek}
PPOSProfile[t]=dictb PPOSProfile[t]=dictb
PPOSProfileString=json.dumps(PPOSProfile, indent=5) PPOSProfileString=json.dumps(PPOSProfile, indent=5)
t+=1 t+=1
#write json file #write json file
PPOSProfileFile.write(PPOSProfileString) PPOSProfileFile.write(PPOSProfileString)
\ No newline at end of file
import StringIO
out = StringIO.StringIO()
book.save(out)
book.save('DP.xls')
return out.getvalue()
if __name__ == '__main__':
with open('DemandProfile.xls', 'w') as outputfile:
outputfile.write(generateDemandPlanning('Input8PPOS.xlsx'))
# ===========================================================================
# Copyright 2013 University of Limerick
#
# This file is part of DREAM.
#
# DREAM is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DREAM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with DREAM. If not, see <http://www.gnu.org/licenses/>.
# ===========================================================================
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment