Crazy Bug in setDomainValueFormat - androidplot

I changed the sample code SimpleXYPlotActivity to format a domain label like this:
// create a couple arrays of y-values to plot:
Number[] domainLabels = {1, 2, 3, 6, 7, 8, 9, 10, 13, 14};
Number[] series1Numbers = {1, 4, 2, 8, 4, 16, 8, 32, 16, 64};
Number[] series2Numbers = {5, 2, 10, 5, 20, 10, 40, 20, 80, 40};
// turn the above arrays into XYSeries':
// (Y_VALS_ONLY means use the element index as the x value)
//XYSeries series1 = new SimpleXYSeries(Arrays.asList(series1Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series1");
XYSeries series1 = new SimpleXYSeries(Arrays.asList(domainLabels), Arrays.asList(series1Numbers), "Series1");
//XYSeries series2 = new SimpleXYSeries(Arrays.asList(series2Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2");
XYSeries series2 = new SimpleXYSeries(Arrays.asList(domainLabels), Arrays.asList(series2Numbers), "Series2");
//...other lines
plot.setDomainValueFormat(new Format() {
#Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
int day = ((Number) obj).intValue();
System.out.println(day);
return new StringBuffer(day);
}
#Override
public Object parseObject(String source, ParsePosition pos) {
return null;
}
});
// reduce the number of range labels
//plot.setTicksPerRangeLabel(3);
// rotate domain labels 45 degrees to make them more compact horizontally:
plot.getGraphWidget().setDomainLabelOrientation(-45);
I dont know why, but plot print the following domain labels:
1, 2, 3, 5, 6, 8, 9, 11, 12, 13
and not the right values...
1, 2, 3, 6, 7, 8, 9, 10, 13, 14
Why has it this crazy behaviour?

Well to start, when I run the above code, no labels are printed at all. But if I replace:
return new StringBuffer(day);
with:
return toAppendTo.append(day);
Then the labels appear. Moving on...
Your formatter is truncating the floating point x-val associated with each domain tick label. The reason you have this floating point component is because you are specifying your own xVals when you instantiate SimpleXYSeries. I suspect that what you really want is to specify iVals only, since you dont actually create xVals anywhere.
I made these changes:
First, create your XYSeries instances to create xVals from iVals like this:
XYSeries series1 = new SimpleXYSeries(Arrays.asList(series1Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series1");
XYSeries series2 = new SimpleXYSeries(Arrays.asList(series2Numbers),SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2");
Next, update your domain formatter to use your domain label lookup array like this:
plot.setDomainValueFormat(new Format() {
#Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
int i = Math.round(((Number) obj).floatValue());
return toAppendTo.append(domainLabels[i]);
}
#Override
public Object parseObject(String source, ParsePosition pos) {
return null;
}
});
For anyone wondering why obj is first converted to a float and then rounded to an int before being used as an iVal: This is necessary to avoid the natural flooring behavior that occurs when converting float values to int values. If for example you were to call intValue on a Double representation of 1, you'd get 0 because internally it's represented as 0.99999999... and gets floored to 0 by the conversion instead of being rounded up to 1.

Related

Median array index in an array of 5 values

I have an array of 5 numbers in Excel VBA.
Each array index number is an x coordinate and the array value at each index is the Y coordinate/value. I'm trying to find the "median" x coordinate in the array based on the y values within the array.
Example 1:
Array(1) = 1, Array(2) = 0, Array(3) = 1, Array(4) = 1, Array(5) = 2
I envisage the x coordinate median would be (after rounding) index 4 - are there functions in Excel would support determining this or perhaps some suggested code please?
Example 2:
Array(1) = 7, Array(2) = 1, Array(3) = 4, Array(4) = 7, Array(5) = 1
I envisage the x coordinate median would be (after rounding) index 3?
Example 3:
Array(1) = 1, Array(2) = 0, Array(3) = 0, Array(4) = 0, Array(5) = 6
I envisage the x coordinate median would be (after rounding) index 5?
Example 4:
Array(1) = 5, Array(2) = 0, Array(3) = 7, Array(4) = 0, Array(5) = 6
I envisage the x coordinate median would be (after rounding) index 3?
Thanks in advance!
I don't think your definitions above are an accurate description, namely the x and y co ords.
Nonetheless, you are dealing with a 1 dimensional array and you are trying to find the median within it. As such, by the definition of a median, you need to reorganise your array in numerical order and find the number that divides the array in it's "upper" half and "lower" half. Once you establish this, you can either reference this number by it's orginal index value (x co ord by your definition), or it's new index value.
Let's go through your first example above for clarity.
Example 1 above:
Array(1) = 1, Array(2) = 0, Array(3) = 1, Array(4) = 1, Array(5) = 2
As such:
Array = Array(1, 0, 1, 1, 2)
Reordered:
Array(0, 1, 1, 1, 2)
As can be seen from above the only transformation that needs to occur is that the original index 1 and 2 need reordering to achieve this. If this is the route you have taken then index 3 (x co ord) will be your median index for the values within the array.
In closing, I think your median value will rely on a) the transformation you do from non-ordered to ordered, and b) the index value of the NEW array.
Hope this helps!

Retrieve one value from default dict on python 3

I have a dict which I populate with data using setdefault method as follows:
if date not in call_dict:
call_dict.setdefault(date, [0, 0]).append(0)
else:
call_dict[date][0] += 1
if x[12] != 'ANSWERED':
call_dict[date][1] += 1
call_dict[date][2] = 100*(call_dict[date][1]/call_dict[date][0])
At the end of this process I have a dict which is structured like this:
{'key' : value0, value1, value2}
Then I have to plot only key and value2 (as value2 is a function of the key) but I can't find the way to access this value.
I tried myDict.values() but it did not work (as expected). I would really like to avoid creating another list/dict/anything because of script performance and also to achieve
that I would still have to reach for the value2 which would solve my problem.
Any ideas how to solve this problem?
Sample values of dict:
{'08:23': [45, 17, 37.77777777777778],
'08:24': [44, 15, 34.090909090909086],
'08:25': [46, 24, 52.17391304347826],
'08:48': [49, 19, 38.775510204081634],
You can get them from the dictionary with a list comprehension:
data = { "2018-07-01": [45, 17, 37.77777777777778],
"2018-07-02": [44, 15, 34.090909090909086],
"2018-07-03": [46, 24, 52.17391304347826],
"2018-07-04": [49, 19, 38.775510204081634]}
xy = [(x,data[x][2]) for x in data.keys()] # extract tuples of (date-key, 3rd value)
print(xy)
Output:
[('2018-07-01', 37.77777777777778), ('2018-07-02', 34.090909090909086),
('2018-07-03', 52.17391304347826), ('2018-07-04', 38.775510204081634)]
If you need them for plotting you might want to do:
x,y = zip(*xy)
print(x)
print(y)
Output:
('2018-07-01', '2018-07-02', '2018-07-03', '2018-07-04') # x
(37.77777777777778, 34.090909090909086, 52.17391304347826, 38.775510204081634) # y
and supply those to your plotting library as x and y data.
Doku: zip(*iterables)

how to filter () a pairRDD according to two conditions

how can i filter my pair RDD if i have 2 conditions for filter it , one to test the key and the other one to test the value (wanna the portion of code) bcz i used this portion and it didnt work saddly
JavaPairRDD filtering = pairRDD1.filter((x,y) -> (x._1.equals(y._1))&&(x._2.equals(y._2)))));
You can't use regular filter for this, because that checks one item at a time. You have to compare multiple items to each other, and check which one to keep. Here's an example which only keeps items which are repeated:
val items = List(1, 2, 5, 6, 6, 7, 8, 10, 12, 13, 15, 16, 16, 19, 20)
val rdd = sc.parallelize(items)
// now create an RDD with all possible combinations of pairs
val mapped = rdd.map { case (x) => (x, 1)}
val reduced = mapped.reduceByKey{ case (x, y) => x + y }
val filtered = reduced.filter { case (item, count) => count > 1 }
// Now print out the results:
filtered.collect().foreach { case (item, count) =>
println(s"Keeping $item because it occurred $count times.")}
It's probably not the most performant code for this, but it should give you an idea for the approach.

How to implement a function change_value_at_index that takes in three parameters: a tuple, an index, and a new value?

Implement a function
change_value_at_index
that takes in three parameters: a tuple, an index, and a new value, and changes the value at the index to the new value. The function should return the modified tuple. If index is out of range, return the original tuple.
for example, change_value_at_index((1, 2, 3), 1, -1) = (1, -1, 3)
for example, change_value_at_index((1, 2, 3, 4, 5), -2, 'huh') = (1, 2, 3, 'huh', 5)
def change_value_at_index(tpl, index, value):
# Your code here
How do I do this? I am really clueless. Thanks for your help! Also, I must use Python 3.x.
def change_value_at_index(tpl, index, value):
# Your code here
if index >= len(tpl) or index < -len(tpl):
return tpl
else:
a = tpl[:index] + (value,) + tpl[index+1:]
return a

how to find the empty spot in a row?

I am suppose to put a group of people (given at run-time) in to a 2 dimensional array of spot, group together in a row randomly(find out all possible positions and randomly pick one)
To start of, I wanna try in an array first
if I have an array of spots of size 10 like below
spots[occupied,open,open,occupied,occupied,occupied,open,open,open,open]
to put 2 people
Is there a particular algorithm to do this kind of problem?
Thanks for any help!
in python:
seats =["occupied","open","open","occupied","occupied","occupied","open","open","open","open"]
def empty(seats,index,count):
if count == 0:
return True
else:
return (seats[index] == "open") & empty(seats,index+1,count-1)
def findEmpty(seats,count):
result = []
for (i=0;i<seats.size-count+1,i++)
if empty(seats,i,count):
result.append(<list of consecutive numbers from i to i+count>)
return result
print findEmpty(seats,2)
>>>[[1, 2], [6, 7], [7, 8], [8, 9]]
here's another approach, its a little more efficient:
seats = ["occupied","open","open","occupied","occupied","occupied","open","open","open","open"]
//counts the number of consecutive free seats starting at position index
def countEmpty(seats,index):
if index >= len(seats) or seats[index] == "occupied":
return 0
return 1 + countEmpty(seats,index+1)
def findEmpty(seats,count):
result = []
i = 0
while i < len(seats)-count+1:
c = countEmpty(seats,i)
if c>=count:
for (j=i;j<i+c-count+1;j++):
result.append(<list of consecutive numbers from j to j+count>)
i += 1 + c
return result
print findEmpty(seats,2)
>>>[[1, 2], [6, 7], [7, 8], [8, 9]]
and finally, if you did choose to use python you could do it in one line:
seats =["occupied","open","open","occupied","occupied","occupied","open","open","open","open"]
count = 2
print [range(i,i+count) for i in range(len(seats)-count+1) if all([seats[j]=="open" for j in range(i,i+count)]) ]
>>> [[1, 2], [6, 7], [7, 8], [8, 9]]
Pseudo code:
//Create 2 lists of blocks, both empty: tmp and final
List tmp=new List;
List final=new List;
//Cycle the seats
for (int i=0;i<length(seats);i++) {
//If the seat is occupied, start over
if (seats[i]==occupied) tmp.empty();
else {
//Cycle existing block candidates, add free seat
foreach (ref block in tmp) {
block.add(seats[i])
if (length(block)>=people_count) {
//HEUREKA, got a fitting block: Move it to the final list
tmp.remove(block)
final.add(block)
}
}
//Start a new block with this seat
tmp.add(new block(seats[i]));
//Read below for this edge case
}
}
final now has the blocks.
If you allow the edge case of people_num being 1, you have to check for a complete block at the position indicated in the pseudocode
I shall use Mathematica code but I believe you can follow the logic.
Starting with:
dat = spots[occupied, open, open, occupied, occupied, occupied, open, open, open, open];
fill = {"Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"};
First find a random permutation of the list fill (it is easy to find an algorithm on StackOverflow):
randomfill = RandomSample # fill
{"Delta", "Echo", "Alpha", "Bravo", "Charlie", "Foxtrot"}
Then "map" a function onto each element of the spots list, and if the element is open return the next value from the randomfill list, else return the element unchanged:
i = 1;
If[# === open, randomfill[[i++]], #] & /# dat
spots[occupied, "Delta", "Echo", occupied, occupied, occupied, "Alpha", "Bravo", "Charlie", "Foxtrot"]

Resources