Search This Blog
2020/12/30
Javascript : Higher Order function
FOR IN & FOR OF Loops in javascript
For In loop is used to loop through keys of an object while for of loop is used to loop through array element.
Consider following array ,we want to iterate through values of this array.
Example 1:
let arr = ["sagar","sangram","sachin","swapnil","gaurav","swara"]
for(let elt of arr)
{
console.log(`Element ${elt}`);
}
Output:Element sagar
Element sangram
Element sachin
Element swapnil
Element gaurav
Element swara
Example 2:As we know string is essentially character array.
let str ="india is my country";
for(let char of str)
{
console.log(`${char}`);
}
Output:
i
n
d
i
a
i
s
m
y
c
o
u
n
t
r
y
For In Loop:consider following code snippet.Our object obj keys we want to iterate.It can be done as follows
Example 3:
let obj = {
name:"sangram",
city:"mumbai",
state:"maharashtra",
pin:"416602",
language:"marathi",
knowEnglish :"yes"
}
for(let key in obj)
{
console.log(`Key: ${key} Value: ${obj[key]}` );
}
Output:
Key: name Value: sangram
Key: city Value: mumbai
Key: state Value: maharashtra
Key: pin Value: 416602
Key: language Value: marathi
Key: knowEnglish Value: yes
We should use this alternate implementation of traditional for loop whenever feasible it is simple & concise.
Lets take look at traditional way to loop object keys.
Traditional Way using for loop:
Example 4:
let obj = {
name:"sangram",
city:"mumbai",
state:"maharashtra",
pin:"416602",
language:"marathi",
knowEnglish :"yes"
}
for(let i=0;i < Object.keys(obj).length;i++)
{
console.log(`Key: ${Object.keys(obj)[i]} and Value ${obj[Object.keys(obj)[i]]}`)
}
Output:
Key: name and Value sangram
Key: city and Value mumbai
Key: state and Value maharashtra
Key: pin and Value 416602
Key: language and Value marathi
Key: knowEnglish and Value yes
One more way of looping using Object.entries:
Example 5:
for(let entry of Object.entries(obj))
{
console.log(`Key: ${entry[0]} # Value: ${entry[1]}`)
}
Output:
Key: name # Value: sangram
Key: city # Value: mumbai
Key: state # Value: maharashtra
Key: pin # Value: 416602
Key: language # Value: marathi
Key: knowEnglish # Value: yes
we can also use foreach on object keys array to loop through.
Example 6:
let entries = Object.entries(obj)
for(let entry of entries)
{
console.log(`Key: ${entry[0]} # Value: ${entry[1]}`)
}
let keys = Object.keys(obj);
keys.forEach((element,index) => {
console.log(`Key: ${element} , Index: ${index} ,Value:${obj[element]}`)
});
Output:
Key: name , Index: 0 ,Value:sangram
Key: city , Index: 1 ,Value:mumbai
Key: state , Index: 2 ,Value:maharashtra
Key: pin , Index: 3 ,Value:416602
Key: language , Index: 4 ,Value:marathi
Key: knowEnglish , Index: 5 ,Value:yes
2020/12/27
Javascript:Currying
2020/12/26
Javascript Prototype Basics
Prototypes are the mechanism by which JavaScript objects inherit features from one another. Methods & properties of prototype are inherited by object.
Lets create two classes mobile & samsung.samsung class is special case of mobile class.
//mobile class
let mobile = function(w,h,b)
{
this.width = w;
this.height = h;
this.breadth =b;
}
mobile.prototype.breadth = 50
mobile.prototype.printDimension = function()
{
console.log(`width:${this.width} ,height:${this.height},breadth:${this.breadth}`);
}
samsung class inheriting from mobile class
//samsung class
let samsung = function(w,h,b,s)
{
//calling constructor
mobile.call(this,w,h,b);
this.stylus = s;
this.printDimension = function()
{
console.log(`width:${this.width} ,height:${this.height},breadth:${this.breadth},stylus:${this.stylus}`);
}
}
//samsung inherits from mobile
samsung.prototype = Object.create(mobile.prototype);
Here mobile is base class of samsung class.
Lets create objects of both class
//create object of mobile
let m1 = new mobile(300,500,50);
//mobile object
console.log("m1 properties:");
console.log("width:" + m1.width)
console.log("height:" + m1.height)
console.log("breadth:" + m1.breadth)
console.log("stylus:" +m1.stylus)
m1.printDimension();
//create object of samsung
let s1 = new samsung(400,600,45,'stylus pen');
//samsung object
console.log("\n");
console.log("s1 properties:");
console.log("width:" +s1.width)
console.log("height:" +s1.height)
console.log("bredth;" + s1.breadth)
console.log("stylus:" + s1.stylus)
s1.printDimension();
Lets see output.
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/proto-type$ node index.js
m1 properties:
width:300
height:500
breadth:50
stylus:undefined
width:300 ,height:500,breadth:50
s1 properties:
width:400
height:600
bredth;45
stylus:stylus pen
width:400 ,height:600,breadth:45,stylus:stylus pen
Here stylus is property of child class that is why it is not available in m1 the mobile class object which is base class.
We defined breadth as
mobile.prototype.breadth = 50
meaning breath is member of prototype of mobile but
samsung.prototype = Object.create(mobile.prototype);
says samsung’s prototype is mobile’s prototype so breath is available in objects of both class.
PrintDimension method written in prototype so it is common between all objects of mobile which saves duplication.if it is instance method it will be member of each object instantiated from mobile class.
We have overriden this method in Child class.So when PrintDimension method is called on child class it has additional information of stylus.
Properties written directly in class are called instance property while written in prototype are called prototype properties.
Class inheriting properties & method from prototype that in turn inherit from its prototype till last entity object,prototype of object is null.this is called prototype chaining.
2020/12/24
export & exports in Node.js
We will look into export & import functionality of node.js
Reusable
code written in js file is exported then called from other places by importing this functionality.
Lets create a project as follows
sangram@sangram-HP-Laptop-15-bs0xx:~/projects$ mkdir destructering/
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ npm init -y
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ touch index.js
Open Visual Studio Code editor here & add a folder utils,Inside utils as index.js
utils/index.js
function Add(a,b)
{
return a+b;
}
function Substract(a,b)
{
return a-b;
}
function Multiply(a,b)
{
return a*b;
}
function Divide(a,b)
{
return a/b;
}
module.exports ={Add,Substract,Multiply,Divide}
At bottom of this file we have module.export which exports our four functions.
One can export some function while keeping other unexported.e.g.
module.exports ={Add,Multiply}
Here we are exporting only two functions.
We can assign names different from function name at time of exports as follows
module.exports ={sub:Substract,div:Divide}
Other syntax to export:
exports.Add= function(a,b)
{
return a+b;
}
exports.Substract = function (a,b){
return a-b;
}
exports.Multiply = function (a,b){
return a*b;
}
exports.Divide = function (a,b){
return a/b;
}
exports.PI = 3.14;Not neccessary to import only function you can import const also here PI is imported.
ES6 Syntax:
export function Add(a,b)
{
return a+b;
}
export function Substract(a,b)
{
return a-b;
}
export function Multiply(a,b){
return a*b;
}
export function Divide(a,b)
{
return a/b;
}
export const PI = 3.14;
Another Way in Es6:
function Add(a, b) {
return a + b;
}
function Substract(a, b) {
return a - b;
}
function Multiply(a, b) {return a * b;
}
function Divide(a, b) {return a / b;
}
const PI = 3.14;
export { Add, Multiply, PI };
To test Es6 syntax install babel:
npm install --save-dev babel-cli babel-preset-es2015 rimraf
into package.json add two more command
"build": "rimraf dist/ && babel ./ --out-dir dist/ --ignore ./node_modules,./.babelrc,./package.json,./npm-debug.log --copy-files",
"start": "npm run build && node dist/index.js"
and create .babelrc file in root add following to it.
{
"presets": ["es2015"]
}
to run project us npm start.
Default Export:
Lets create new file area.js in util to show default export syntax.
utils/area.js
export default function cube(x) {
return x * x * x;
}
Its imported as follows
import cube from './utils/area.js'
Now I added one more function beside cube as follows.
export default function cube(x) {
return x * x * x;
}
export function square(x){
return x * x;
}
Newly added function is imported as follows
import {square} from './utils/area.js'
My index.js file where i am testing this function looks like below.
import {Add,Multiply,PI} from'./utils/index.js'
import cube from './utils/area.js'
import {square} from './utils/area.js'
var addition = Add(5,7)
console.log(`addition: ${addition}`);
var multiply = Multiply(5,7)
console.log(`multiply: ${multiply}`);
console.log(`PI = ${PI}`);
var cube_area = cube(3);
console.log(`cube_area: ${cube_area}`);
var square_area = square(3);
console.log(`square_area : ${square_area }`);
Exports From :
create middleman.js inside utils. And add following
export { square } from './area.js';
Now replace following
import {square} from './utils/area.js'
with
import {square} from './utils/middleman.js'
in index.js our entrypoint file.
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ npm start
> destructering@1.0.0 start
> npm run build && node dist/index.js
> destructering@1.0.0 build
> rimraf dist/ && babel ./ --out-dir dist/ --ignore ./node_modules,./.babelrc,./package.json,./npm-debug.log --copy-files
index.js -> dist/index.js
utils/area.js -> dist/utils/area.js
utils/index.js -> dist/utils/index.js
utils/middleman.js -> dist/utils/middleman.js
addition: 12
multiply: 35
PI = 3.14
cube_area: 27
square_area : 9
Our code will run with same output.
Here in middleman.js we are exporting square by taking from area.js.
Array & Object Destructuring in Javascript
The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
We will learn destructuring by examples.
Array Destructuring:
Choosing Only Few elements only:
const array =[100,500,390,60]
let [a,b,c] = array
console.log(`${a},${b},${c}`)
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
100,500,390
Here we choose only 3 elements rest is not chosen.Order is important,array element get assigned to variable in an order.
Assigning Default value:
const array =[100,500,390,60]
let [a,b,c,d,e=78] = array
console.log(`${a},${b},${c},${d},${e}`)
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
100,500,390,60,78
Here you observe that 5 th array element is not defined it has assigned default value of 78 which it gets.
Skipping In between:
const array =[100,500,390,67,78,34,56,60]
let [a,b,,,,f,,h] = array
console.log(`${a},${b} ${f},${h}`)
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
100,500 34,60
To skip element just add comma without variable.
Rest Syntax:
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(rest);
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
[ 30, 40, 50 ]
Here variable a & b get consecutive values and rest variable get remaining one.
Variable declaration moved up:
const array =[100,500,390,60]
let a,b,c,d,e;
[a,b,c,d,e=78] = array
console.log(`${a},${b},${c},${d},${e}`)
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
100,500,390,60,78
Here declaration is decoupled from destructing syntax.
Object Destructuring:
Choose Few keys only:
const favourites ={
"bird":"peacock",
"ant":"red ant",
"fruit":"mango",
"tree":"coconut"
};
let {bird,ant} =favourites;
console.log(`${bird},${ant}`)
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
peacock,red ant
rest Syntax:
const favourites ={
"bird":"peacock",
"ant":"red ant",
"fruit":"mango",
"tree":"coconut"
};
let {bird,ant,...rest} =favourites;
console.log(`${bird},${ant}`)
console.log(rest);
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
peacock,red ant
{ fruit: 'mango', tree: 'coconut' }
Rest Must be last element:
const favourites ={
"bird":"peacock",
"ant":"red ant",
"fruit":"mango",
"tree":"coconut"
};
let {bird,ant,...rest,tree} =favourites;
console.log(`${bird},${ant},${tree}`)
console.log(rest);
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
/home/sangram/projects/destructering/index.js:8
let {bird,ant,...rest,tree} =favourites;
^^^^
SyntaxError: Rest element must be last element
at wrapSafe (node:internal/modules/cjs/loader:1024:16)
at Module._compile (node:internal/modules/cjs/loader:1072:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
at Module.load (node:internal/modules/cjs/loader:973:32)
at Function.Module._load (node:internal/modules/cjs/loader:813:14)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12)
at node:internal/main/run_main_module:17:47
In our case in destructing syntax rest is not last element so we are getting error.
Order is not Important:
const favourites ={
"bird":"peacock",
"ant":"red ant",
"fruit":"mango",
"tree":"coconut"
};
let {bird,ant,tree,fruit} =favourites;
console.log(`${bird},${ant},${fruit},${tree}`)
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
peacock,red ant,mango,coconut
Here tree comes before fruit yet irrespective of order values fetched correctly.
Default Value:
const favourites ={
"bird":"peacock",
"ant":"red ant",
"fruit":"mango",
"tree":"coconut"
};
let {bird,ant,tree,fruit,machine="laptop"} =favourites;
console.log(`${bird},${ant},${fruit},${tree},${machine}`)
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
peacock,red ant,mango,coconut,laptop
Here in favourite object there is no key called machine so it get default value.
Initialization is decoupled from destructering Syntax:
const favourites ={
"bird":"peacock",
"ant":"red ant",
"fruit":"mango",
"tree":"coconut"
};
let bird,ant,tree,fruit,machine;
({bird,ant,tree,fruit,machine="laptop"} =favourites);
console.log(`${bird},${ant},${fruit},${tree},${machine}`)
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
peacock,red ant,mango,coconut,laptop
Rest syntax:
const favourites ={
"bird":"peacock",
"ant":"red ant",
"fruit":"mango",
"tree":"coconut"
};
let {bird,ant,...rest} =favourites;
console.log(`${bird},${ant}`)
console.log(rest);
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
peacock,red ant
{ fruit: 'mango', tree: 'coconut' }
Skipping is not required as you can choose only required keys:
const favourites ={
"bird":"peacock",
"ant":"red ant",
"fruit":"mango",
"tree":"coconut"
};
let {bird,ant,tree} =favourites;
console.log(`${bird},${ant},${tree}`)
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
peacock,red
ant,coconut
Passing paramter to function:
const favourites ={
"bird":"peacock",
"ant":"red ant",
"fruit":"mango",
"tree":"coconut"
};
function PrintFavourite({ant,bird})
{
console.log(`${ant},${bird}`)
}
PrintFavourite(favourites)
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
red ant,peacock
Here function get required paramter from object.
Passing default value to function:
const favourites ={
"bird":"peacock",
"ant":"red ant",
"fruit":"mango",
"tree":"coconut"
};
function PrintFavourite({ant,bird,machine="laptop"})
{
console.log(`${ant},${bird},${machine}`)
}
PrintFavourite(favourites)
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
red ant,peacock,laptop
Combined Array and Object Destructuring
const drinks = [
{ id: 1, name: 'Fizz'},
{ id: 2, name: 'Mangola'},
{ id: 3, name: 'Fanta'}
];
const [,, { name }] = drinks;
console.log(name);
Output:
sangram@sangram-HP-Laptop-15-bs0xx:~/projects/destructering$ node index.js
Fanta
Here is array destructing syntax 2 elements are skipped and from third name is picked.
2020/12/20
How to Upload File in QT C++
We added a line edit to save path of file to be uploaded,First user clicks on Browse button then FileOpenDialogBox is shown from which selected file path comes in LineEdit.After that he clicks on upload button the file get copied to uploads folder beside executable.
On Browse button click we have following code
QString fileName = QFileDialog::getOpenFileName(this,tr("Libre Office File"),
"",tr("Libre Office File (*.odt);;All Files (*)")); ui->lineEdit->setText(fileName); which basically select file and save path to LineEdit. On click of upload button we have following code //current working directory QString location = QDir::currentPath() + "/uploads"; qDebug() << "Current working Dir:" +location ; //create directory if not exist if (! QDir(location).exists()) { QDir().mkdir(location); qDebug() << "Creating Path:" +location ; } //source path QString source = ui->lineEdit->text(); //get file name to append to destination path QFileInfo fi(source); QString name = fi.fileName(); //to make filename unique appending timestamp QString time = QString::number(QDateTime::currentMSecsSinceEpoch()); //make to be full destination file path QString destination = QDir(location).filePath(time + "_" + name); qDebug() << "Destination:" +destination; bool status = QFile::copy(ui->lineEdit->text(),destination); if(status) { QMessageBox::information(this,"Upload Status","File Uploaded Successfully at " + location); ui->lineEdit->setText(""); }else{ QMessageBox::warning(this,"Upload Status","File Upload at " + location + " Failed"); }
It first takes current working Directory appends uploads to end in path,then create directory if not exist. Now to avoid same file name upload overwrite file we are appending timestamp to destination filename.Latter on status of copy we are showing corresponding Message.
Point to note that destination path is not project folder but path where executable is generated for debug.
Code for project is avilable at https://github.com/gitsangramdesai/Qt-CPP-FileUploads.
2020/12/17
QT C++ Showing data in QTableWidget.
Design UI as shown below
We are using Label , LineEdit & QtableWidget.Wriiten a LoadData method that populate QtableWidget
void LoadData(Ui::MainWindow* ui) { QSqlDatabase db; db = QSqlDatabase::addDatabase("QMYSQL","MyConnect"); db.setHostName("localhost"); db.setUserName("root"); db.setPassword("sangram"); db.setDatabaseName("sangram"); int rowIndex =0; if (db.open()) { QSqlQuery query(QSqlDatabase::database("MyConnect")); query.prepare("SELECT * FROM MyUser"); if(query.exec()) { ui->tableWidget->setRowCount(query.size()); ui->tableWidget->setColumnCount(4); ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "Id" << "ShortName" << "Telephone"<<"SAVE"); while(query.next()) { QString id = query.value(0).toString(); QString ShortName = query.value(1).toString(); QString tel = query.value(2).toString(); //data columns QTableWidgetItem* item1 = new QTableWidgetItem(); item1->setText(id); ui->tableWidget->setItem(rowIndex,0,item1); QTableWidgetItem* item2 = new QTableWidgetItem(); item2->setText(ShortName); ui->tableWidget->setItem(rowIndex,1,item2); QTableWidgetItem* item3 = new QTableWidgetItem(); item3->setText(tel); ui->tableWidget->setItem(rowIndex,2,item3); rowIndex = rowIndex +1; } } } //set text field empty ui->leID->setText(""); ui->leName->setText(""); ui->leTel->setText(""); }
also after populating data it empty our textboxes.
In TableLayout’s click event we are setting value for textboxes by fetching it from corresponding column
void MainWindow::on_tableWidget_cellClicked(int row, int column) { QString Id = ui->tableWidget->item(row,0)->text(); QString name = ui->tableWidget->item(row,1)->text(); QString tel = ui->tableWidget->item(row,2)->text(); ui->leID->setText(Id); ui->leName->setText(name); ui->leTel->setText(tel); ShowMsg("Clicked2-" + QString::number(row)); }
There is PushButton against textboxes to save data from textboxes.
void MainWindow::on_pbSubmit_clicked() { QSqlDatabase db; db = QSqlDatabase::addDatabase("QMYSQL","MyConnect"); db.setHostName("localhost"); db.setUserName("root"); db.setPassword("sangram"); db.setDatabaseName("sangram"); QString name = ui->leName->text(); QString tel = ui->leTel->text(); QString id = ui->leID->text(); if (db.open()) { QMessageBox::information(this,"Connection","Connection Success"); QSqlQuery query(QSqlDatabase::database("MyConnect")); if(id =="") { query.prepare("INSERT INTO MyUser(shortName,tel)values(:shortName,:telephone)"); query.bindValue(":shortName",name); query.bindValue(":telephone",tel); }else{ query.prepare("UPDATE MyUser SET shortName=:shortName ,tel=:tel where id=:id"); query.bindValue(":shortName",name); query.bindValue(":tel",tel); query.bindValue(":id",id); } if(query.exec()) { LoadData(ui); QMessageBox::information(this,"Insertion","Insertion Success"); }else { QMessageBox::information(this,"Insertion","Insertion failed"); } }else{ QMessageBox::information(this,"Connection","Connection failed"); } }
Code in Action looks like
When we select row from this grid it get available for editing.
The code for this project is available at https://github.com/gitsangramdesai/qt-mysql-QtableWidget.