Lets say I have QTableWidget that looks like this:
__| columnname1 | columnname2
1 | name1 | value1
2 | name2 | value2
3 | name3 | value3
4 | name4 | value4
that I created with this code:
ui->tableWidget->setColumnCount(2);
foreach(const QString& key, keys)
{
value = jsonObj.value(key);
ui->tableWidget->sortItems(int (1),Qt::DescendingOrder);
int currRow = ui->tableWidget->rowCount();
ui->tableWidget->setSortingEnabled(false);
ui->tableWidget->insertRow(ui->tableWidget->rowCount());
ui->tableWidget->setItem(currRow, 0, new QTableWidgetItem(key));
ui->tableWidget->setItem(currRow, 1, new QTableWidgetItem(value.toString()));
ui->tableWidget->setHorizontalHeaderLabels({"columnname1", "columnname2"});
ui->tableWidget->setSortingEnabled(true);
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
Now, for example, I have a new value for name2, how can I replace that entire row where name2 is?
First of all, you're calling some functions for every row that only need to be called once for the full table. Instead, your code sample should look more like this:
ui->tableWidget->setColumnCount(2);
ui->tableWidget->setSortingEnabled(false);
ui->tableWidget->setHorizontalHeaderLabels({"columnname1", "columnname2"});
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
foreach(const QString& key, keys)
{
value = jsonObj.value(key);
int currRow = ui->tableWidget->rowCount();
ui->tableWidget->insertRow(ui->tableWidget->rowCount());
ui->tableWidget->setItem(currRow, 0, new QTableWidgetItem(key));
ui->tableWidget->setItem(currRow, 1, new QTableWidgetItem(value.toString()));
}
ui->tableWidget->sortItems(int (1),Qt::DescendingOrder);
ui->tableWidget->setSortingEnabled(true);
Then, if you have a new value for the row 'name2', you only need to replace the value. You already know how to do that:
// first find the row index of row 'name2':
int rowIdx = -1;
for(int i = 0; i < ui->tableWidget->rowCount(); i++) {
if(ui->tableWidget->item(i, 0)->text() == "name2") {
rowIdx = i;
break;
}
}
if(rowIdx >= 0) {
// then EITHER replace the item:
ui->tableWidget->setItem(rowIdx, 1, new QTableWidgetItem(value.toString()));
// OR replace the data:
ui->tableWidget->item(rowIdx, 1)->setText(value.toString());
}
I didn't compile this sample code, it could have typos or wrong function names, but you'll get the idea.
Related
I used a google script that move row from one sheet to another from column A to column D. On column E i have a formula. How can i put data on last row from Column A to D from example, ignoring formula from column E. Can someone help me with this?
function onEdit(e){
let r = e.range;
if (r.columnStart != 4 || r.rowStart == 1 || e.value == null) return;
const sh = SpreadsheetApp.getActive();
const valArray = ["Waiting","In progress","Complete"];
const destArray = ["Order","Open order","Complete order"];
let dest = sh.getSheetByName(destArray[valArray.indexOf(e.value)]);
let src = sh.getActiveSheet();
if (dest.getName() == src.getName()) return;
src.getRange(r.rowStart,1,1,4).moveTo(dest.getRange(dest.getLastRow()+1,1,1,4));
src.deleteRow(r.rowStart);
}
Here an example of my problem, maybe this will explain better:https://docs.google.com/spreadsheets/d/1qowADCPYiyej25ezXtjVLO5fvg9Gr9rolX3bh2-ZAG4/edit#gid=0
Replace dest.getLastRow() by dest.getLastDataRow('A') and add this function:
Object.prototype.getLastDataRow = function(col){
var lastRow = this.getLastRow();
var range = this.getRange(col + lastRow);
if (range.getValue() !== "") {
return lastRow;
} else {
return range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
}
};
I still sugest you to erase all formulas in column E and put in E1
={"price * 2";ARRAYFORMULA(if(C2:C>0;C2:C*2;""))}
so that the formula will populate / will be active the new row
In the current database, I select all from a pet table, there is exactly 1 record and it has two DATE field, one for the birth date and one for the death date.
My record has a value for the birth date and a NULL for the death date.
Header files
#include <iostream>
#include <mysqlx/xdevapi.h>
using directives
using ::std::cout;
using ::std::endl;
using namespace ::mysqlx;
First I connect the session
Session sess("<session uri>");
Then I output some information about the table
std::string schema_name = sess.getDefaultSchemaName();
cout << "schema_name : " << schema_name << endl;
Schema db_schema = sess.getSchema( schema_name, true );
std::string table_name { "pet" };
Table pet_table = db_schema.getTable( table_name, true );
cout << "table " << table_name << " has " << pet_table.count() << " row(s). is_view=" << std::boolalpha << pet_table.isView() << std::endl;
Finally I prepare my query
std::stringstream query_writer;
query_writer << "SELECT * FROM " << table_name;
std::string query_str = query_writer.str();
SqlStatement query = sess.sql(query_str);
Then get my results:
SqlResult res = query.execute();
Row pet;
while( (pet = res.fetchOne()) ) {
int count = res.getColumnCount();
for( int column = 0; column < count; column++ ) {
const Column& current_column = res.getColumn( column );
const Value& field_value = pet[column];
const std::string& field_name = current_column.getColumnName();
Type field_type= current_column.getType();
// HOW to Interpret this?
const bytes& raw_bytes = field_value.getRawBytes();
}
}
It was pointed out to me that DATE fields encoding are described in this link:
https://dev.mysql.com/doc/internals/en/date-and-time-data-type-representation.html
but non-null DATE field raw_bytes is 4 bytes long, not 3 bytes long, so where is the correct documentation?
Originally, the table had a DATE field, now it is changed for a DATETIME field:
mysql> describe pet;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name | varchar(20) | YES | | NULL | |
| owner | varchar(20) | YES | | NULL | |
| species | varchar(20) | YES | | NULL | |
| sex | char(1) | YES | | NULL | |
| birth | datetime | YES | | NULL | |
| death | datetime | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
Here are the records in the tabe:
mysql> select * from pet;
+----------+-------+---------+------+---------------------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+---------------------+-------+
| Puffball | Diane | hamster | f | 1999-03-30 00:00:00 | NULL |
+----------+-------+---------+------+---------------------+-------+
1 row in set (0.00 sec)
We had the same issue and developed the following C++20 helper methods for production use with mysqlx (MySQL Connector/C++ 8.0 X DevAPI) to properly read DATE, DATETIME and TIMESTAMP fields:
#pragma once
#include <vector>
#include <cstddef>
#include <chrono>
#include <mysqlx/xdevapi.h>
namespace mysqlx {
static inline std::vector<uint64_t>
mysqlx_raw_as_u64_vector(const mysqlx::Value& in_value)
{
std::vector<uint64_t> out;
const auto bytes = in_value.getRawBytes();
auto ptr = reinterpret_cast<const std::byte*>(bytes.first);
auto end = reinterpret_cast<const std::byte*>(bytes.first) + bytes.second;
while (ptr != end) {
static constexpr std::byte carry_flag{0b1000'0000};
static constexpr std::byte value_mask{0b0111'1111};
uint64_t v = 0;
uint64_t shift = 0;
bool is_carry;
do {
auto byte = *ptr;
is_carry = (byte & carry_flag) == carry_flag;
v |= std::to_integer<uint64_t>(byte & value_mask) << shift;
++ptr;
shift += 7;
} while (is_carry && ptr != end && shift <= 63);
out.push_back(v);
}
return out;
}
static inline std::chrono::year_month_day
read_date(const mysqlx::Value& value)
{
const auto vector = mysqlx_raw_as_u64_vector(value);
if (vector.size() < 3)
throw std::out_of_range{"Value is not a valid DATE"};
return std::chrono::year{static_cast<int>(vector.at(0))} / static_cast<int>(vector.at(1)) / static_cast<int>(vector.at(2));
}
static inline std::chrono::system_clock::time_point
read_date_time(const mysqlx::Value& value)
{
const auto vector = mysqlx_raw_as_u64_vector(value);
if (vector.size() < 3)
throw std::out_of_range{"Value is not a valid DATETIME"};
auto ymd = std::chrono::year{static_cast<int>(vector.at(0))} / static_cast<int>(vector.at(1)) / static_cast<int>(vector.at(2));
auto sys_days = std::chrono::sys_days{ymd};
auto out = std::chrono::system_clock::time_point(sys_days);
auto it = vector.begin() + 2;
auto end = vector.end();
if (++it == end)
return out;
out += std::chrono::hours{*it};
if (++it == end)
return out;
out += std::chrono::minutes{*it};
if (++it == end)
return out;
out += std::chrono::seconds{*it};
if (++it == end)
return out;
out += std::chrono::microseconds{*it};
return out;
}
} //namespace
Which can then be used as follows:
auto row = table.select("datetime", "date").execute().fetchOne();
auto time_point = read_date_time(row[0]);
auto year_month_day = read_date(row[1]);
I've read your question and the whole discussion on dev.mysql before making my own topic because I had exactly the same question. It's been a while since you asked this, but here is the answer: How is date encoded/stored in MySQL?
In a nutshell, the last two bytes are the month and the day respectively, and the first two encode the year so that you can calculate them using the following equation:
N1 - 128 + N2 * 128
It seems that the logic of encoding is to erase the most significant bit of the first number and to write the second number from this erased bit like this:
2002 from 210 and 15:
1101 0010 -> _101 0010;
0000 1111 + _101 0010 -> 0111 1101 0010
2048 from 128 and 16:
1000 0000 -> _000 0000
0001 0000 + _000 0000 -> 1000 0000 0000
From here (getBytes() part) https://dev.mysql.com/doc/dev/connector-cpp/8.0/classmysqlx_1_1abi2_1_1r0_1_1_row.html
I've found out that:
The raw bytes are as received from the server. In genral the value
is represented using x-protocol encoding that corresponds to the type
and other meta-data of the given column. This meta-data can be
accessed via Column object returned by RowResult#getColumn() method.
Values of type DATE and TIMESTAMP use the same representation as
DATETIME, with time part empty in case of DATE values.
Brand new to haskell and I need to print out the data contained on a seperate row for each individual item
Unsure on how to
type ItemDescr = String
type ItemYear = Int
type ItemPrice = Int
type ItemSold = Int
type ItemSales = Int
type Item = (ItemRegion,ItemDescr,ItemYear,ItemPrice,ItemSold,ItemSales)
type ListItems = [Item]
rownumber x
| x == 1 = ("Scotland","Desktop",2017,900,25,22500)
| x == 2 = ("England","Laptop",2017,1100,75,82500)
| x == 3 = ("Wales","Printer",2017,120,15,1800)
| x == 4 = ("England","Printer",2017,120,60,7200)
| x == 5 = ("England","Desktop",2017,900,50,45000)
| x == 6 = ("Wales","Desktop",2017,900,20,18000)
| x == 7 = ("Scotland","Printer",2017,25,25,3000)
showall
--print??
So for example on each individual line
show
"Scotland","Desktop",2017,900,25,22500
followed by the next record
Tip 1:
Store the data like this
items = [("Scotland","Desktop",2017,900,25,22500),
("England","Laptop",2017,1100,75,82500),
("Wales","Printer",2017,120,15,1800),
("England","Printer",2017,120,60,7200),
("England","Desktop",2017,900,50,45000),
("Wales","Desktop",2017,900,20,18000),
("Scotland","Printer",2017,25,25,3000)]
Tip 2:
Implement this function
toString :: Item -> String
toString = undefined -- do this yourselves
Tip 3:
Try to combine the following functions
unlines, already in the Prelude
toString, you just wrote it
map, does not need any explanation
putStrLn, not even sure if this is a real function, but you need it anyway.
($), you can do without this one, but it will give you bonus points
I am trying to figure out how to use slickgrid to display my object in a single column and not in a single row. Below is an example. Ideas?
Grid data looks like this
[{ fname: 'john', lname:'doe'}, {fname:'kyle', lname:'noobie'}]
This is what I get with slickgrid (row object view)
desc | fname | lanme
option1 | john | doe
option2 | kyle | noobie
This is what I want (column object view)
desc | option1 | option2
fname | john | kyle
lname | doe | noobie
So I figured this out and it's not pretty. Basically I have to pivot the data into a new row objects and then unpivot it back out to save it. It's not really that pretty but it gets the job done. The crazy thing is now you have to create a single editor and formatter for and apply that to each column. The editor/formatter look at the field names and do switch statement to determine what it should look like. Have fun. I did. :)
function getPivotedRows(origData) {
//this is a mapping between the column headings and the properties
var properties = [{ 'First Name': 'fname' }, { 'Last Name': 'lname' }];
//this holds my pivoted rows
var rows = [];
for (var i = 0; i < properties.length; i++) {
var row = {};
for (var j = 0; j < origData.length; j++) {
var key = "";
for (var p in properties[i]) {
row['Description'] = p; //set the column
key = properties[i][p];
}
row['options' + (j + 1)] = origData[j][key];
}
row[gridOptions.uniqueKey] = i;
rows.push(row);
}
return rows;
}
A premise, I'm not a programmer, I'm a physicist and I use c++ as a tool to analyze data (ROOT package). My knowledge might be limited!
I have this situation, I read data from a file and store them in a vector (no problem with that)
vector<double> data;
with this data I want to plot a correlation plot, so I need to split them up in two different subsets one of which will be the X entries of a 2D histogram and the other the Y entries.
The splitting must be as follow, I have this table (I only copy a small part of it just to explain the problem)
************* LBA - LBC **************
--------------------------------------
Cell Name | Channel | PMT |
D0 | 0 | 1 |
A1-L | 1 | 2 |
BC1-R | 2 | 3 |
BC1-L | 3 | 4 |
A1-R | 4 | 5 |
A2-L | 5 | 6 |
BC2-R | 6 | 7 |
BC2-L | 7 | 8 |
A2-R | 8 | 9 |
A3-L | 9 | 10 |
A3-R | 10 | 11 |
BC3-L | 11 | 12 |
BC3-R | 12 | 13 |
D1-L | 13 | 14 |
D1-R | 14 | 15 |
A4-L | 15 | 16 |
BC4-R | 16 | 17 |
BC4-L | 17 | 18 |
A4-R | 18 | 19 |
A5-L | 19 | 20 |
...
None | 31 | 32 |
as you can see there are entries like A1-L and A1-R which corresponds to the left and right side of one cell, to this left and right side are associated an int that corresponds to a channel, in this case 1 and 4. I wish these left and right side to be on the X and Y axis of my 2D histogram.
The problem is then to associate to the vector of data somehow this table so that I can pick the channels that belongs to the same cell and put them one on the X axis and the other on the Y axis. To complicate the things there are also cells that don't have a partner like in this example D0 and channels that don't have a cell associated like channel 31.
My attempted solution is to create an indexing vector
vector<int> indexing = (0, 1, 4, ....);
and an ordered data vector
vector<double> data_ordered;
and fill the ordered vector with something like
for( vector<int> iterator it = indexing.begin(); it != indexing.end(); ++it)
data_ordered.push_back(data.at(*it));
and then put the even index of data_ordered on the X axis and the odd values on the Y axis but I have the problem of the D0 cell and the empty ones!
Another idea that I had is to create a struct like
struct cell{
string cell_name;
int left_channel;
int right_channel;
double data;
....
other informations
};
and then try to work with that, but there it comes my lack of c++ knowledge! Can someone give me an hint on how to solve this problem? I hope that my question is clear enough and that it respects the rules of this site!
EDIT----------
To clarify the problem I try to explain it with an example
vector<double> data = (data0, data1, data2, data3, data4, ...);
do data0 has index 0 and if I go to the table I see it corresponds to the cell D0 which has no other partner and let's say can be disregarded for now. data1 has index 1 and it corresponds to the left part of the cell A1 (A1-L) so I need to find the right partner which has index 4 in the table and ideally leads me to pick data4 from the vector containing the data.
I hope this clarify the situation at least a little!
Here is an engine that does what you want, roughly:
#include <vector>
#include <map>
#include <string>
#include <iostream>
enum sub_entry { left, right, only };
struct DataType {
std::string cell;
sub_entry sub;
DataType( DataType const& o ): cell(o.cell), sub(o.sub) {};
DataType( const char* c, sub_entry s=only ):
cell( c ),
sub( s )
{}
DataType(): cell("UNUSED"), sub(only) {};
// lexographic weak ordering:
bool operator<( DataType const& o ) const {
if (cell != o.cell)
return cell < o.cell;
return sub < o.sub;
}
};
typedef std::vector< double > RawData;
typedef std::vector< DataType > LookupTable;
typedef std::map< DataType, double > OrganizedData;
OrganizedData organize( RawData const& raw, LookupTable const& table )
{
OrganizedData retval;
for( unsigned i = 0; i < raw.size() && i < table.size(); ++i ) {
DataType d = table[i];
retval[d] = raw[i];
}
return retval;
}
void PrintOrganizedData( OrganizedData const& data ) {
for (OrganizedData::const_iterator it = data.begin(); it != data.end(); ++it ) {
std::cout << (*it).first.cell;
switch( (*it).first.sub ) {
case left: {
std::cout << "-L";
} break;
case right: {
std::cout << "-R";
} break;
case only: {
} break;
}
std::cout << " is " << (*it).second << "\n";
}
}
int main() {
RawData test;
test.push_back(3.14);
test.push_back(2.8);
test.push_back(-1);
LookupTable table;
table.resize(3);
table[0] = DataType("A1", left);
table[1] = "D0";
table[2] = DataType("A1", right);
OrganizedData org = organize( test, table );
PrintOrganizedData( org );
}
The lookup table stores what channel maps to what cell name and side.
Unused entries in the lookup table should be set to DataType(), which will flag their values to be stored in an "UNUSED" location. (It will still be stored, but you can discard it afterwards).
The result of this is a map from (CellName, Side) to the double data. I included a simple printer that just dumps the data. If you have graphing software, you can figure out a way to make a graph from it. Skipping "UNUSED" is an exercise that involves checking (*it).first.cell == "UNUSED" in that printing loop.
I believe everything is C++03 compliant. A bunch of the above becomes prettier if you had a C++11 compiler.