PHPSpreadsheet: getHighestDataRow/getHighestDataColumn after fromArray - phpspreadsheet

I'm using fromArray to load an array of data into a worksheet. This is working fine. After doing so, getHighestDataColumn and getHighestDataRow do not seem to be updated. Is there a way to force PHPSpreadsheet to recalculate these values after calling fromArray?
[edit] An update seems to have fixed the issue.

Be aware to not use the github#PHPExcel lib if you're still using them.
They've said to update to its directly successor, which is beig maintained and recently updated at github#PhpSpreadsheet
Recently Microsoft released an update which breaks some of the functionalities when we use the old lib.
Getting this example from their doc, you could try using the fromArray():
To set data from an array:
$arrayData = [
[NULL, 2010, 2011, 2012],
['Q1', 12, 15, 21],
['Q2', 56, 73, 86],
['Q3', 52, 61, 69],
['Q4', 30, 32, 0],
];
$sheet->getActiveSheet()
->fromArray(
$arrayData, // The data to set
NULL, // Array values with this value will not be set
'C3' // Top left coordinate of the worksheet range where
// we want to set these values (default is A1)
);
Then you follow this to extract data from the spreadsheet:
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
// Loop for each row
for ($row = 0; $row <= $highestRow; $row++) {
// here you extract the columns for that row
$columns = array_shift(array_values($sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, FALSE)));
}

Related

Dart fill ByteData with List<int>

List<int> l = [ 1, 2, 3, 4 ];
var b = ByteData(10);
May I know what is the easiest way to fill b (position 4 ~ 7) with data from l.
I can certainly iterate through l and then fill b one by one. But this is just part of a larger solution. So I hope there is a simpler way (for easy maintenance in future).
ByteData represent an area of memory counted in bytes but does not tell us anything how we want to represent the data inside this block of memory.
Normally, we would use one of the specific data types from dart:typed_data like e.g. Uint8List, Int8List, Uint16List and so on which have a lot more functionality.
But you can easily get the same by making a view over your ByteData. In this example I guess you want to insert your numbers as Uint8:
import 'dart:typed_data';
void main() {
List<int> l = [ 1, 2, 3, 4 ];
var b = ByteData(10);
var uInt8ListViewOverB = b.buffer.asUint8List();
uInt8ListViewOverB.setAll(4, l);
print(uInt8ListViewOverB); // [0, 0, 0, 0, 1, 2, 3, 4, 0, 0]
}
I recommend reading the documentation for the different methods on ByteBuffer (returned by buffer). You can e.g. make subview of a limited part of your ByteData if your ByteData needs to contain different types of data:
https://api.dart.dev/stable/2.15.0/dart-typed_data/ByteBuffer/asUint8List.html

Wireshark dissect information but not display in the dissect

This may have been explained elsewhere, but not finding it. I have to work within the confines of wireshark 2.4.x.
So I defined some values for data as so.
{ &hf_td_timestamp,
{ "Timestamp", "td.timestamp",
FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL
} },
{ &hf_td_timestamp_sec,
{ "Timestamp Seconds", "td.timestamp.sec",
FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL
} },
{ &hf_td_timestamp_nsec,
{ "Timestamp nSeconds", "td.timestamp.nsec",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
} },
and the data for one of them gets stored and added to the dissect tree as so
proto_tree_add_item(td_tree, hf_td_timestamp, tvb, offset, 8, ENC_TIME_TIMESPEC);
I only want to display the one line item and not all three. The information for the other two are of course derived from the same bytes. Ultimately I would like to have the other fields available for adding to the columns and not the detail dissect.
That is part 1. Once I can establish the storing of the information I will of course add the other two as a single line into the detail as seconds.nanoseconds. The values just need to be stored separately so that the data can be parsed in an Excel csv file. Excel cannot handle the precision of the nanoseconds in decimal format, that is why they must be separate.
Part 2: store some metadata that is calculated from known fields. Specifically the delta between these timestamps. Wireshark can give the delta of the recorded timestamp but not the timestamp within the payload. So basically store the delta between the payload timestamp with the same port information as the last packet from the same port. Once I can get past part 1 then I should be able to accomplish part 2.
So, is there a function that will parse the tvb and only store the value as opposed to store to be displayed?
proto_tree_add_item(td_tree, hf_td_timestamp, tvb, offset, 8, ENC_TIME_TIMESPEC);
proto_item * ti_sec = proto_tree_add_item(td_tree, hf_td_timestamp_sec, tvb, offset-4, 8, ENC_BIG_ENDIAN);
proto_item * ti_nsec = proto_tree_add_item(td_tree, hf_td_timestamp_nsec, tvb, offset+4, 8, ENC_BIG_ENDIAN);
PROTO_ITEM_SET_HIDDEN(ti_sec);
PROTO_ITEM_SET_HIDDEN(ti_nsec);
If the proto_tree_add_item() appears in the PROTO_ITEM_SET_HIDDEN() then the item will be displayed. PROTO_ITEM_SET_HIDDEN() works on previously declared items not currently created items.As for part 2:The metadata was created by generating a GHashTable for each new metadata item to hold the payload timestamps for each of the line numbers. (If there is a better way I would like to know. Like access the completed list if stored in wireshark as opposed to creating my own). Generate my timestamp deltas and convert the values into a tvb, then read the tvb back to store in the fields.
GHashTable * timestamp_map = NULL;
GHashTable * timestamp_delta = NULL;
.
.
.
// Store the timestamp (key = linenum, value = timestamp)
timestamp_map = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
// Store the list of line numbers from the associated client
timestamp_delta = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_list_free);
.
.
.
// find your deltas through your lookups
// convert to tvb and then to fields
// Create a new TVB to delta
tvbuff_t *tvbtmp = tvb_new_real_data(vals.buffer, 8, 8);
// Store in the field hf_tu_timestamp_delta
proto_tree_add_item(tree, hf_tu_timestamp_delta, tvbtmp, 0, 8, ENC_LITTLE_ENDIAN);
NOTE: For very large captures the memory usage will be large (very large and expensive).

Ignite ML with multiple preprocessing

Using Ignite machine learning, say I have a labeled dataset like this:
IgniteCache<Integer, LabeledVector<Integer>> contents = ignite.createCache(cacheConfiguration);
contents.put(1, new LabeledVector<Integer>(new DenseVector(new Serializable[] { 705.2, "HD", 29.97, 1, 1, 96.13 }), 2));
contents.put(2, new LabeledVector<Integer>(new DenseVector(new Serializable[] { 871.3, "HD", 30, 1, 1, 95.35 }), 3));
contents.put(3, new LabeledVector<Integer>(new DenseVector(new Serializable[] { 2890.2, "SD", 29.97, 1, 1, 95.65 }), 10));
contents.put(4, new LabeledVector<Integer>(new DenseVector(new Serializable[] { 1032, "SD", 29.97, 1, 1, 96.8 }), 4));
How would I use the NormalizationTrainer on features 0 and 5 but the EncoderTrainer on feature 1? I think I'm having difficulties understanding how to concatenate multiple preprocessing before finally feeding the model trainer.
What I currently have is this (modified Ignite sample):
Vectorizer<Integer, LabeledVector<Integer>, Integer, Integer> vectorizer = new LabeledDummyVectorizer<Integer, Integer>(0, 5);
Preprocessor<Integer, LabeledVector<Integer>> preprocessor1 = new NormalizationTrainer<Integer, LabeledVector<Integer>>().withP(1).fit(ignite, data, vectorizer);
Preprocessor<Integer, LabeledVector<Integer>> preprocessor2 = new EncoderTrainer<Integer, LabeledVector<Integer>>().withEncoderType(EncoderType.STRING_ENCODER).withEncodedFeature(1).fit(ignite, data, preprocessor1);
KNNClassificationTrainer trainer = new KNNClassificationTrainer();
KNNClassificationModel mdl = trainer.fit(ignite, data, preprocessor2);
Do I understand the multiple preprocessor correctly? If so, how would I add another BinarizationTrainer on feature 2? I think I'm getting confused by where to specify which feature to apply the preprocessing trainer on. For one trainer (NormalizationTrainer) I have to use the Vectorizer to tell which features to use, for the EncoderTrainer I can do this as a method function. How would I then add BinarizationTrainer with another Vectorizer?
One preprocessor builds on top of another.
Coordinates are relative to the preprocessor that comes before.
This example shows how to accomplish what you want to do:
https://github.com/apache/ignite/blob/master/examples/src/main/java/org/apache/ignite/examples/ml/tutorial/Step_6_KNN.java
put a breakpoint here: https://github.com/apache/ignite/blob/eabe50d90d5db2d363da36393cd957ff54a18d90/modules/ml/src/main/java/org/apache/ignite/ml/preprocessing/encoding/EncoderTrainer.java#L93
to see how the String Encoder references coordinates
examine all the variables:
UpstreamEntry<K, V> entity = upstream.next(); //this is the row from the file
LabeledVector<Double> row = basePreprocessor.apply(entity.getKey(), entity.getValue()); //after the previous preprocessor has been applied
categoryFrequencies = calculateFrequencies(row, categoryFrequencies); //use the given coordinates to calculate results.
more about preprocessing: https://apacheignite.readme.io/docs/preprocessing
Alternatively, you can use the pipelines API for a more streamlined approach to preprocessing: https://apacheignite.readme.io/docs/pipeline-api

Equivalent for Java System.arraycopy in Dart?

How do I convert the below java code to equivalent dart.
private static final byte[] mIdBytes = new byte[]{(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x7E};
byte[] data;
System.arraycopy(mIdBytes, 2, data, 0, 4);
Is there any Dart method that does a similar kind of operation?
I was looking into this:
https://pub.dev/documentation/ckb_dart_sdk/latest/ckb-utils_number/arrayCopy.html
To match Java's System.arrayCopy(source, sourceOffset, target, targetOffset, length)
you should use
target.setRange(targetOffset, targetOffset + length, source, sourceOffset);
This is more efficient than using List.copyRange for some lists, for example copying between typed-data lists with the same element size (like two Uint8Lists).
Well, I found the way to do it.
you can just use
List.copyRange(data, 0, mIdBytes, 2);
This is a workaround I kinda found to be done in your case. This is called sublist(), this method will take the start index, and an end index.
IDEA:
Use sublist(), and copy the elements to be started from, that sourcePos = you_pos
Source array will be used like sourceArray.sublist(startIndext, endIndex)
The destination array will be initialized with the value using sublist()
Till what length the item should be added would be mentioned in the end index+2, since it will ignore the last item, and copy till the index-1
FINAL CODE
void main() {
List<int> source = [1, 2, 3, 4, 5, 6];
List<int> target = [];
int startPos = 1;
int length = 4;
// to ensure the length doesn't exceeds limit
// length+2 because, it targets on the end index, that is 4 in source list
// but the end result should be length+2 to contain a length of 5 items
if(length+1 <= source.length-1){
target = source.sublist(startPos, length+2);
print(target);
}else{
print('Cannot copy items till $length: index out of bound');
}
}
//OUTPUT
[2, 3, 4, 5, 6]

Highcharts not rendering data points

I'm pulling some data from a database that I'm trying to render into a Highcharts stock chart. The data is pulled from the database with PHP and passed to the chart with a $.get(..php/line-data.php) call, and the data retrieved is supposed to be the data that is rendered on the chart.
The data is being returned in the following manner, and I have verified this by logging data in the console. It appears as such, with the first value being the UNIX-to-Javascript converted date/time (x-axis), and the second being the value (y-axis):
[[1362639600000, 8],[1362726000000, 20],[1362985200000, 28],[1363071600000, 51],[1363158000000, 64],[1363244400000, 11],[1363330800000, 4],[1363503600000, 4],[1363590000000, 21],[1363676400000, 10],[1363762800000, 31],[1363849200000, 13],[1363935600000, 17],[1364194800000, 10],[1364454000000, 1],[1365058800000, 30],[1365145200000, 10],[1366009200000, 55],[1366182000000, 18],[1366268400000, 22],[1366354800000, 12]]
As an experiment, I tried just plugging this data straight into a basic demo Fiddle, and it seems to render fine.
FIDDLE HERE.
So what am I doing incorrectly? Everything seems to be set up correctly, but it's not rendering. This is what I see:
Here are the relevant portions of my code. Yes, I know that mysql_* is deprecated...I'll change it.
$.get('../php/line-data.php', function(data) {
window.chart = new Highcharts.StockChart({
chart : {
renderTo : 'total_mentions',
margin: [20, 10, 10, 10],
spacingTop: 0,
spacingBottom: 1,
spacingLeft: 0,
spacingRight: 0
},
series : [{
name : 'Total Mentions',
data: data,
type:'line',
lineWidth:1,
shadow:false,
states: {
hover: {
lineWidth:1
}
},
id : 'dataseries',
tooltip : {
valueDecimals: 4,
borderColor:'#DA7925',
borderRadius: 0,
borderWidth: 1,
shadow: false
},
color:'#DA7925',
fillOpacity:0.2
}]
[more options...etc.]
No problems with this code. It's pulling the correct data and echoing how I expect it to.
<?php
$expAddress = "URL";
$expUser = "USERNAME";
$expPwd = "PASSWORD";
$database = "DB";
$db = mysql_connect($expAddress, $expUser, $expPwd);
mysql_select_db($database, $db);
$ok = mysql_query("
SELECT
DATE(created_at) AS create_date,
COUNT(id) AS total
FROM
tweets
WHERE
subject LIKE 'word1'
OR
subject LIKE 'word2'
GROUP BY
DATE(created_at)");
if (!$ok) {
echo "<li>Mysql Error: ".mysql_error()."</li>";
}
else {
while($row = mysql_fetch_assoc($ok)){
extract($row);
$date = strtotime($create_date);
$date *= 1000;
$data[] = "[$date, $total]";
}
$tmp = join($data,',');
echo "[".$tmp."]";
}
?>
Have you tried parsing your data (string) into a javascript object before setting it to the series[i].data?
series : [{
data: JSON.parse(data)
}]
What you are getting from php through $.get is basically string and NOT a javascript array of array of numbers, which is what you want. It may look like that, but it is as simple as "5"!=5, but parseInt("5")==5 same is the case with json objects, you need to parse the string into such an object before javascript or highcharts can interpret it correctly, highcharts could do it on your behalf, but it is not designed that way.
Try his fiddle to get an idea of the data types in picture
var data="[[1362639600000, 8],[1362726000000, 20],[1362985200000, 28],[1363071600000, 51],[1363158000000, 64],[1363244400000, 11],[1363330800000, 4],[1363503600000, 4],[1363590000000, 21],[1363676400000, 10],[1363762800000, 31],[1363849200000, 13],[1363935600000, 17],[1364194800000, 10],[1364454000000, 1],[1365058800000, 30],[1365145200000, 10],[1366009200000, 55],[1366182000000, 18],[1366268400000, 22],[1366354800000, 12]]"
console.log(typeof data); //string
var parsedData=JSON.parse(data);
console.log(typeof parsedData); //object
console.log(typeof parsedData[0]); //object [1362639600000, 8]
console.log(typeof parsedData[0][0]); //number 1362639600000
When you paste the console value directly in the fiddle, you are actually pasting it as a valid javascript array, try using your console value wrapped by " quotes " and see that the exact issue is reproduced!!
Demo # jsFiddle
An alternate approach could be using the $.getJSON() method instead. jQuery does the parsing for you before it calls your callback method
Your problem is in either the output from the PHP script or when you receive the data in your Javascript (quite obvious).
First, don't do JSON by hand use json_encode (http://php.net/manual/en/function.json-encode.php). It's easier and it will guarantee that strings will be escaped properly.
Secondly, inspect your data variable with a debugger. You could also post the exact content of the variable to the question.
But basically, as long as it is working in the fiddle and not in your program you have not yet reproduced the error in your code properly in the fiddle.
For instance, you could replace data in your callback with the data you have in your fiddle to see if the code runs.

Resources