1 # -*- coding: utf-8 -*-
2 from __future__
import unicode_literals
3 from functools
import reduce
5 from com
.sun
.star
.awt
.MessageBoxType
import MESSAGEBOX
, INFOBOX
, WARNINGBOX
, ERRORBOX
, QUERYBOX
6 from com
.sun
.star
.awt
.MessageBoxButtons
import BUTTONS_OK
, BUTTONS_OK_CANCEL
, BUTTONS_YES_NO
, BUTTONS_YES_NO_CANCEL
, BUTTONS_RETRY_CANCEL
, BUTTONS_ABORT_IGNORE_RETRY
7 from com
.sun
.star
.awt
.MessageBoxResults
import OK
, YES
, NO
, CANCEL
8 from com
.sun
.star
.sheet
import CellFlags
10 if 'XSCRIPTCONTEXT' in globals():
12 return XSCRIPTCONTEXT
.getDocument()
17 from dev
import getModel
, debug
22 profilSheet
= doc
.Sheets
[0]
23 valueSheet
= doc
.Sheets
[1]
24 rankingSheet
= doc
.Sheets
[2]
25 ClearSheet(valueSheet
)
26 ClearSheet(rankingSheet
)
28 profilCursor
= getUsedArea(profilSheet
)
29 profilRange
= profilCursor
.RangeAddress
30 profilData
= list(map(lambda x
: list(x
), list(profilCursor
.getDataArray())))
32 nChoices
= len(profilData
) - 1
33 nGrades
= len(profilData
[0]) - 1
34 nJudges
= sumCells(profilData
[1][1:nGrades
+1])
35 debug("nJudges:"+str(nJudges
))
36 debug("profilData:"+str(profilData
))
38 for choice
in range(1,nChoices
+1):
39 choiceGrades
= profilData
[choice
]
40 choiceJudges
= sumCells(choiceGrades
[1:nGrades
+1])
41 debug("choice:"+str(choice
))
42 debug(" choiceJudges:"+str(choiceJudges
))
43 debug(" choiceGrades:"+str(choiceGrades
))
45 # Check profilData consistency
46 if choiceJudges
!= nJudges
:
47 MsgBox(ERRORBOX
, BUTTONS_OK
, "MajorityJudgment", \
48 "Choice "+choiceGrades
[0]+" has "+str(choiceJudges
)+" judgments" \
49 + "\nbut the first choice has "+str(nJudges
)+" judgments." \
50 + "\nAborting. Fix the profil and retry.")
56 while nJudgesLower
*2 < nJudges
:
57 medianGrade
= medianGrade
+ 1
58 nJudgesLower
= nJudgesLower
+ intOfCell(choiceGrades
[medianGrade
])
59 debug(" medianGrade:"+str(medianGrade
))
61 # Extend choiceValue with the overflow of the lower judgments
62 choiceValue
= [choiceGrades
[0]]
64 lowerMedianGrade
= medianGrade
65 higherMedianGrade
= medianGrade
+ 1
66 nJudgesHigher
= nJudges
- nJudgesLower
67 while nJudgesLower
> nJudgesHigher
:
68 while intOfCell(choiceGrades
[lowerMedianGrade
]) == 0:
70 choiceGrades
[lowerMedianGrade
] -= 1
71 choiceValue
.append(lowerMedianGrade
-1)
75 # Extend choiceValue by alterning between lower and higher judgments
76 while valueCol
< nJudges
:
78 while intOfCell(choiceGrades
[lowerMedianGrade
]) == 0:
80 while intOfCell(choiceGrades
[higherMedianGrade
]) == 0:
81 higherMedianGrade
+= 1
82 choiceValue
.append(lowerMedianGrade
-1)
83 choiceValue
.append(higherMedianGrade
-1)
84 choiceGrades
[lowerMedianGrade
] -= 1
85 choiceGrades
[higherMedianGrade
] -= 1
88 valueData
.append(choiceValue
)
90 # Write into rankingSheet the profilData sorted according to valueData
91 profilData
= list(profilCursor
.getDataArray())
92 rankingData
= list(zip(profilData
[1:nChoices
+1], valueData
))
93 rankingData
.sort(key
=lambda data
: data
[1][1:nJudges
+1])
95 valueData
= list(map(lambda data
: data
[1], rankingData
))
96 rankingData
= [list(profilData
[0])]+list(map(lambda data
: data
[0], rankingData
))
97 debug("rankingData:"+str(rankingData
))
98 rankingRange
= rankingSheet
.getCellRangeByPosition( \
99 profilRange
.StartColumn
, \
100 profilRange
.StartRow
, \
101 profilRange
.EndColumn
, \
103 rankingRange
.setDataArray(rankingData
)
105 # Write valueData into valueSheet
106 debug("valueData:"+str(valueData
))
107 for value
in valueData
:
109 debug("base:"+str(base
))
110 digits
= list(map(lambda v
: v
, value
[1:nJudges
+1]))
111 rank
= inBase(base
, digits
)
112 rankMax
= base
** nJudges
- 1
113 debug("digits:"+str(digits
))
114 debug("rank:"+str(rank
))
115 debug("rankMax:"+str(rankMax
))
116 value
.insert(1,rank
/ rankMax
)
117 debug("valueData:"+str(valueData
))
118 valueRange
= valueSheet
.getCellRangeByPosition( \
119 profilRange
.StartColumn
, \
120 1+profilRange
.StartRow
, \
121 profilRange
.StartColumn
+ 1 + nJudges
, \
123 valueRange
.setDataArray(valueData
)
125 def inBase(base
, digits
):
128 acc
= digit
+ (base
* acc
)
132 return int(cell
) if cell
!= '' else 0
134 return reduce(lambda x
,y
: intOfCell(x
) + intOfCell(y
), cells
)
135 def getUsedArea(sheet
):
136 profilCursor
= sheet
.createCursor()
137 profilCursor
.gotoStartOfUsedArea(False)
138 profilCursor
.gotoEndOfUsedArea(True)
140 def ClearSheet(sheet
):
141 cursor
= sheet
.createCursor()
142 cursor
.gotoStartOfUsedArea(False)
143 cursor
.gotoEndOfUsedArea(True)
144 rangeAddress
= cursor
.RangeAddress
145 range = sheet
.getCellRangeByPosition( \
146 rangeAddress
.StartColumn
, \
147 rangeAddress
.StartRow
, \
148 rangeAddress
.EndColumn
, \
149 rangeAddress
.EndRow
)
150 flags
= CellFlags
.VALUE | \
151 CellFlags
.DATETIME | \
153 CellFlags
.ANNOTATION | \
154 CellFlags
.FORMULA | \
155 CellFlags
.HARDATTR | \
157 CellFlags
.OBJECTS | \
159 range.clearContents(flags
)
160 def MsgBox(msgtype
, buttons
, title
, message
):
162 parentwin
= doc
.CurrentController
.Frame
.ContainerWindow
163 toolkit
= parentwin
.getToolkit()
164 msgbox
= toolkit
.createMessageBox(parentwin
, msgtype
, buttons
, title
, message
)
165 ret
= msgbox
.execute()