dropzone.js Change display units - dropzone.js

Does anyone know if it's possible to change the units display for uploaded files? I uploaded a file that is 600 MB, and the display says 0.6 Gib... It's not real user friendly. I've checked the instructions on the website, and cannot find anything beyond how to change the filesizeBase from 1000 to 1024.

I had a similar need because I had to show the units always on KB. I found a function in dropzone.js called filesize and I just overwritten it by the next one on my own code:
Dropzone.prototype.filesize = function(size) {
var selectedSize = Math.round(size / 1024);
return "<strong>" + selectedSize + "</strong> KB";
};
I think you have to overwrite the same function but adapt it for your needs.
I hope is still useful for you.

This is more similar to the existing filesize function included in Dropzone (except more verbose).
Dropzone.prototype.filesize = function (bytes) {
let selectedSize = 0;
let selectedUnit = 'b';
let units = ['kb', 'mb', 'gb', 'tb'];
if (Math.abs(bytes) < this.options.filesizeBase) {
selectedSize = bytes;
} else {
var u = -1;
do {
bytes /= this.options.filesizeBase;
++u;
} while (Math.abs(bytes) >= this.options.filesizeBase && u < units.length - 1);
selectedSize = bytes.toFixed(1);
selectedUnit = units[u];
}
return `<strong>${selectedSize}</strong> ${this.options.dictFileSizeUnits[selectedUnit]}`;
}
Example:
339700 bytes -> 339.7 KB (instead of 0.3 MB which is what Dropzone returns by default)
Source: https://stackoverflow.com/a/14919494/1922696

This piece of code works for me:
Dropzone.prototype.filesize = function (bytes) {
let selectedSize = 0;
let units = ['B', 'KB', 'MB', 'GB', 'TB'];
var size = bytes;
while (size > 1000) {
selectedSize = selectedSize + 1;
size = size/1000;
}
return "<strong>" + Math.trunc(size * 100)/100 + "</strong> " + units[selectedSize];
}
I'm dividing by 1000, because otherwise I get 1010 KB, instead of 1.01 MB.

Related

Find the combination of a number set so that the total difference between two number sets is minimal

Find the combinations of lots assigned from newLots into oldLots, so that the sum of differences between newLotCombinations and oldLots is optimal.
If a difference is less than 0, it counts as 0.
All lots from newLot must be assigned into newLotCombinations.
/**
*
* e.g.
*
* newLots = [20.16, 9.95, 12.62, 7.44, 11.18, 9.02, 8.21, 8.22, 6.57, 6.63]
* oldLots = [12.03, 14.03, 16.04, 17.8, 18.04, 22.05]
*
* newLotCombinations | oldLot | Difference (newLotCombinations - oldLot)
* 20.16, 9.95 | 12.03 | 18.03 (20.16 + 9.95 - 12.03)
* 12.62, 7.44 | 14.03 | 6.03 (12.62 + 7.44 - 14.03)
* 11.18 | 16.04 | 0
* ...
* ...
* Sum of differences = 18.03 + 6.03 + 0 + ...
*/
I think this should involve memoizing the paths that I have gone through, like a map, and walking backward when a path is not correct (total sum larger than the assumption)
This is what I have so far:
const newLots = [20.16, 9.95, 12.62, 7.44, 11.18, 9.02, 8.21, 8.22, 6.57, 6.63]; // stack
const oldLots = [12.03, 14.03, 16.04, 17.8, 18.04, 22.05];
// newLotCombinations is an array of array [[], [], [], [], [], []] // i and j
const newLotCombinations = oldLots.map(() => []);
// Assuming the max. sum of differences is 5.
const MAX_SUM_OF_DIFFERENCES = 7;
const sum = 0;
// store information about a path?
const paths = {};
const loopLots = (i = 0, j = 0) => {
if (i === -1) {
console.log('it should not come to here');
console.log(
"No possible combination for max sum of differences:",
MAX_SUM_OF_DIFFERENCES
);
} else if (!newLots.length) {
console.log(
"Combination that works with max sum of difference ",
MAX_SUM_OF_DIFFERENCES,
newLotCombinations
);
}
newLotCombinations[i][j] = newLots.pop();
if (getSumOfDifferences() > MAX_SUM_OF_DIFFERENCES) {
// put it back to stack
newLots.push(newLotCombinations[i].pop());
if (i + 1 < newLotCombinations.length) {
loopLots(i + 1, newLotCombinations[i+ 1].length);
} else {
// It keeps popping until an array has more than 1 element.
// But this is incorrect, as it will loop with 3 combinations of numbers
// It should walk backward until last divergence
while (newLotCombinations[i] && (i === newLotCombinations.length - 1 || newLotCombinations[i].length < 2)) {
newLots.push(newLotCombinations[i].pop());
i--;
}
if (newLotCombinations[i]) {
newLots.push(newLotCombinations[i].pop());
newLotCombinations[i + 1][newLotCombinations[i + 1].length] = newLots.pop();
// loopLots(i + 1, newLotCombinations[i + 1].length);
loopLots(0, newLotCombinations[0].length);
} else {
console.log(
"No possible combination for max sum of differences:",
MAX_SUM_OF_DIFFERENCES
);
}
}
} else {
loopLots(0, newLotCombinations[0].length);
}
};
const getSumOfDifferences = () => {
let sumOfDifferences = 0;
newLotCombinations.forEach((lots, i) => {
const lotSum = lots.reduce((sum, lot) => {
sum += lot;
return sum;
}, 0);
const difference = lotSum - oldLots[i];
if (difference > 0) {
sumOfDifferences += difference;
}
});
return sumOfDifferences;
};
loopLots();
The logic of using newLotCombinations[i].length < 2 is incorrect, because it keeps pushing in the same alternating numbers. If I memoize the paths to check whether I should go further, how can I know when I am walking backward or forward if simply saving the paths that I have walked through?
I am thinking I also should not save a subset path. I should save a path that reaches the end (i.e. 6), because a subset of path contains unknown paths ahead.

How to generate random IPv4 number for a given country?

Having IPv4 address ranges for a given country, how would one generate random address? For example, a single current set of ranges (one of many) for Singapore is:
+----------+----------+--------------+
| ip_from | ip_to | country_code |
+----------+----------+--------------+
| 18925568 | 18926079 | SG |
+----------+----------+--------------+
source: lite.ip2location.com
FAQ(3) explains that
IP_Number = 16777216*w + 65536*x + 256*y + z
where
IP_Address = w.x.y.z
IP_Number standing either for ip_from or ip_to. For the Singapore range presented above, it gives me:
16777216*w + 65536*x + 256*y + z >= 18925568; // from
16777216*w + 65536*x + 256*y + z <= 18926079; // to
How can I generate random w, x, y and z?
Here is a testable implementation (in JavaScript since that can be run directly here) and a little bit of a description.
First you need to generate random number from the specified range. If you have a function (let's call it random) that generates random real numbers between 0 and 0.999... [0,1) then you can do this.
num = (random() * (end - start + 1)) + start
Then you need to use mod 256 4 times to split the number into 4 parts and also use div 256 3 times on the given number (the fourth div operation would be unnecessary but if we are doing it in loop then we can just keep it there for the sake of simplicity as it doesn't change a thing).
(% - modulo, // - div)
first = num % 256
num = num // 256
second = num % 256
num = num // 256
third = num % 256
num = num // 256
fourth = num % 256
You can then push them into an array [fourth, third, second, first] (note the order here) and do some validation - some addresses are reserved for private internets so if you happen to generate one of them, just throw it away and generate a new one (you can either loop or recurse here till you generate a valid one).
Ip addresses in these ranges are reserved according to RFC 1918:
10.0.0.0 - 10.255.255.255 (10/8 prefix)
172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
And here is the implementation.
const start = 18925568;
const end = 18926079;
function _generateRandomIp(start, end) {
let r = Math.floor(Math.random() * (end - start + 1)) + start;
const ip = [];
for (let i = 0; i < 4; i++) {
ip.push(r % 256);
r = Math.floor(r / 256);
}
return ip.reverse(); // put the results mod/div into correct order
}
function generateRandomIp(start, end) {
let ip = _generateRandomIp(start, end);
let valid = true;
// ip can't be of format 10.xxx.xxx.xxx
if (ip[0] === 10) { valid = false; }
// ip can't be of format 172.16.xxx.xxx
if (ip[0] === 172 && ip[1] === 16) { valid = false; }
// ip can't be of format 192.168.xxx.xxx
if (ip[0] === 192 && ip[1] === 168) { valid = false; }
if (valid === true) {
return ip.join('.'); // convert ip to string format
} else {
return generateRandomIp(start, end); // try again
}
}
const ip = generateRandomIp(start, end);
console.log(ip);
The above snippet will generate a random ip address in that range each time you run it.
And here is the test case from the page that you have mentioned which says that number 3401190660 should be converted into 202.186.13.4, so let's just switch that randomly generated number for this one and try it.
const start = 18925568;
const end = 18926079;
function _generateRandomIp(start, end) {
let r = 3401190660; // here is that specific number
const ip = [];
for (let i = 0; i < 4; i++) {
ip.push(r % 256);
r = Math.floor(r / 256);
}
return ip.reverse(); // put the results mod/div into correct order
}
function generateRandomIp(start, end) {
let ip = _generateRandomIp(start, end);
let valid = true;
// ip can't be of format 10.xxx.xxx.xxx
if (ip[0] === 10) { valid = false; }
// ip can't be of format 172.16.xxx.xxx
if (ip[0] === 172 && ip[1] === 16) { valid = false; }
// ip can't be of format 192.168.xxx.xxx
if (ip[0] === 192 && ip[1] === 168) { valid = false; }
if (valid === true) {
return ip.join('.'); // convert ip to string format
} else {
return generateRandomIp(start, end); // try again
}
}
const ip = generateRandomIp(start, end);
console.log(ip);
And as we can see, this algorithm produced the correct result.

Javascripts - Auto refresh with random number

I want to generate random number for refresh page
How to set math.random between 20 sec until 50 sec?
My Javascript code looks like this:
var number = Math.random() * 50;
var sec = number - (number % 1) + 20;
var url = "http://example.org";
if (sec == 20 || sec == 30 || sec == 40 || sec == 50)
{
setTimeout(function() { window.location = url } , sec * 1000 );
}
Based on this a suggest following statement:
var sec = Math.floor(Math.random() * (50 - 20) + 20);
I tested it with following script:
<script>
a = 20;
b = 50;
for (i = 0; i < 20; i++)
{
alert(Math.floor(Math.random() * (b - a) + a));
}
</script>
and it has never generated a number lower than 20 and higher than 50.

algorithm used to calculate 5 star ratings

I need to calculate 5-star ratings like the one on Amazon website. I have done enough search to find what is the best algorithm, but I am not able to get a proper answer. For example, if these are the ratings
5 star - 252
4 star - 124
3 star - 40
2 star - 29
1 star - 33
totally 478 reviews
Amazon has calculated this to be "4.1 out of 5 stars". Can anyone tell me how this figure is arrived at? I am not able to get this just by doing average.
That's a weighted average, where you weigh each rating with the number of votes it got:
(5*252 + 4*124 + 3*40 + 2*29 + 1*33) / (252+124+40+29+33) = 4.11 and change
If you are start calculation of overall rating from beginning then this formula will help you.
Formula
((Overall Rating * Total Rating) + new Rating) / (Total Rating + 1)
Example
suppose you have no ratings till now then formula is like,
overall rating is "0" till now.
total rating "0"
and given rating is "4"
((0*0)+4)/1 = 4
If overall rating is "4.11" Total rating is "478" And new rating
giving by one user is "2"
then formula is like
((4.11 * 478)+ 2)/479 // 479 is increment of new rating from 478
a better way to do this,
rating = (sum_of_rating * 5)/sum_of_max_rating_of_user_count
example:
total users rated: 6
sum_of_max_rating_of_user_count: 6 x 5 = 30
sum_of_rating: 25
rating = (25 * 5) / 30
Done!
Yes, you can average them out:
(5 * 252 + 4 * 124 + 3 * 40 + 2 * 29 + 1 * 33) / 478 = 4.11
Super helpful reply by Blindy, here's the PHP code that's based on it. Some may find useful. The results will be 4.11 as per OP's example:
$ratings = array(
5 => 252,
4 => 124,
3 => 40,
2 => 29,
1 => 33
);
function calcAverageRating($ratings) {
$totalWeight = 0;
$totalReviews = 0;
foreach ($ratings as $weight => $numberofReviews) {
$WeightMultipliedByNumber = $weight * $numberofReviews;
$totalWeight += $WeightMultipliedByNumber;
$totalReviews += $numberofReviews;
}
//divide the total weight by total number of reviews
$averageRating = $totalWeight / $totalReviews;
return $averageRating;
}
How to build the above $ratings array
Example pseudo code, but which should work that explains how to build the $ratings array when info is stored in DB assuming you have a table called "ratings" and a column called "rating". In this case it's 1 join, you would need to do 4 joins to get all ratings, but this should get you started:
SELECT count(c1.rating) as one_star, count(c2.rating) as two_star
FROM ratings c1
LEFT OUTER JOIN
ratings c2
ON
c1.id = c2.id
WHERE
c1.rating = 1
AND
c2.rating = 2
another approach suggested in comments
SELECT SUM(rating = 1) AS one_s ,SUM(rating = 2) AS two_s ,SUM(rating = 3) as three_s FROM reviews where product_id = 9
This rating system is based on a weighted average or weighted mean. That is, they used the weight in terms of stars to compute a decimal value which rounds to 4.1. For example:
Sum of (weight * number of reviews at that weight) / total number of reviews
(5*252 + 4*124 + 3*40 + 2*29 + 1*33) / 478 = 4.1
Weighted average, sum the number of stars times its weight, and then divide it through by the total number of reviews.
According to your question your solution will be like this.
Sum of (Rate*TotalRatingOfThatRate)/ TotalNumberOfReviews
((5*252)+(4*124)+(3*40)+(2*29)+(1*33)) / (252+124+40+29+33)
output will be 4.1
in Javascript
function calcAverageRating(ratings) {
let totalWeight = 0;
let totalReviews = 0;
ratings.forEach((rating) => {
const weightMultipliedByNumber = rating.weight * rating.count;
totalWeight += weightMultipliedByNumber;
totalReviews += rating.count;
});
const averageRating = totalWeight / totalReviews;
return averageRating.toFixed(2);
}
const ratings = [
{
weight: 5,
count: 252
},
{
weight: 4,
count: 124
},
{
weight: 3,
count: 40
},
{
weight: 2,
count: 29
},
{
weight: 1,
count: 33
}
];
console.log(calcAverageRating(ratings));
In addition, I am just trying to make practical and full code for all.
My Json Object Array
var yourRatingData =[{
review_id:1,
customer_id:5,
customer_name:"Faysal",
rating:5,
review_content:"I like this product it's cool and best in quality"
},
{
review_id:2,
customer_id:6,
customer_name:"Adams",
rating:4,
review_content:"It's quality product though price a bit high"
},
{
review_id:3,
customer_id:8,
customer_name:"Jane",
rating:3,
review_content:"I like but should improve quality"
},
{
review_id:4,
customer_id:9,
customer_name:"Julia",
rating:1,
review_content:"It's not good"
}];
Rating Calculation
let _5star = yourRatingData.filter(r=>r.rating==5).length;
let _4star = yourRatingData.filter(r=>r.rating==4).length;
let _3star = yourRatingData.filter(r=>r.rating==3).length;
let _2star = yourRatingData.filter(r=>r.rating==2).length;
let _1star = yourRatingData.filter(r=>r.rating==1).length;
//Sum of individual star.
let sumOfRating = parseInt( _5star + _4star + _3star + _2star + _1star );
//Total number of rating
let overallRating = parseInt( 5*_5star + 4*_4star + 3*_3star + 2*_2star +1*_1star );
//Average of all rating
let averageRating = parseFloat(overallRating/sumOfRating);
//Percentage of each star rating
let _5starPercentage = parseInt((_5star/totalRating)*100);
let _4starPercentage = parseInt((_4star/totalRating)*100);
let _3starPercentage = parseInt((_3star/totalRating)*100);
let _2starPercentage = parseInt((_2star/totalRating)*100);
let _1starPercentage = parseInt((_1star/totalRating)*100);
I think it's helpful.
This is an example method using flutter,
double starRating = 5.0;
getRating() {
// ! Check Already Accepted by others or Not -----------------------------------
//
int totalof5s = 0;
int totalof4s = 0;
int totalof3s = 0;
int totalof2s = 0;
int totalof1s = 0;
//
FirebaseFirestore.instance
.collection('usersRating')
.where("passengerUid", isEqualTo: "GNblJJJsjicaA2vkXJNJ6XCAiwa2")
.snapshots()
.forEach((querySnapshot) {
if (querySnapshot.size > 0) {
querySnapshot.docs.forEach((element) async {
if (element["rating"] == 5) {
totalof5s++;
} else if (element["rating"] == 4) {
totalof4s++;
} else if (element["rating"] == 3) {
totalof3s++;
} else if (element["rating"] == 2) {
totalof2s++;
} else if (element["rating"] == 1) {
totalof1s++;
}
//
if (this.mounted) {
setState(() {
starRating = (5 * totalof5s +
4 * totalof4s +
3 * totalof3s +
2 * totalof2s +
1 * totalof1s) /
(totalof5s + totalof4s + totalof3s + totalof2s + totalof1s);
});
}
});
} else {
// This is default one in any case these user doesn't have any rating document exists
if (this.mounted) {
setState(() {
starRating = 5.0;
});
}
}
});
}
(Total nunber of star / total number of persons who review * 5 ) * 5
= Answer
Fixed decimals in js to 1.
answer.toFixed(1);
Example the total reviews of 5 person is 20 star.
(20/5*5)*5 = 4.0
I used this way to calculate ratings and it is working perfectly
let one_star = 0;
let two_star = 0;
let three_star = 0;
let four_star = 0;
let five_star = 0;
Object.values(reviews).forEach(({ rating }) => {
switch (rating) {
case 1: one_star++; break;
case 2: two_star++; break;
case 3: three_star++; break;
case 4: four_star++; break;
case 5: five_star++; break;
}
});
let sum = one_star + two_star + three_star + four_star + five_star;
let average = ((5 * five_star) + (4 * four_star) + (3 * three_star) + (2 * two_star) + (1 * one_star)) / (sum);
console.log(average);

Displaying filesize on the user interface

I have been using following function to display the file size in bytes in more readable uable friendly on the user interface.
function bytesToSize(bytes, precision)
{
var kilobyte = 1024;
var megabyte = kilobyte * 1024;
var gigabyte = megabyte * 1024;
var terabyte = gigabyte * 1024;
if ((bytes >= 0) && (bytes < kilobyte)) {
return bytes + ' B';
} else if ((bytes >= kilobyte) && (bytes < megabyte)) {
return (bytes / kilobyte).toFixed(precision) + ' KB';
} else if ((bytes >= megabyte) && (bytes < gigabyte)) {
return (bytes / megabyte).toFixed(precision) + ' MB';
} else if ((bytes >= gigabyte) && (bytes < terabyte)) {
return (bytes / gigabyte).toFixed(precision) + ' GB';
} else if (bytes >= terabyte) {
return (bytes / terabyte).toFixed(precision) + ' TB';
} else {
return bytes + ' B';
}
}
However the problem is that it shows X KB, X MP ..etc (rounding the results to display on UI) and not able to show X.Y or say X,Y. After this thing thing came to my mind i was more confused and i started looking around the systems for how they show it on there UI. following are some of them,
FileZill : XXX,XXX,XXX bytes (while uploading)
Windows Explorer : XXX, XXX KB (in details view)
Now all these brought me to new level of confusion, as the size displayed on the UI using above function is not really precise imagine file size in GB's which is incorrectly displayed to user.
Please let know in which format this data should be displayed to the users to be more useful at the same time more accurate. Also real estate is expensive in today's complicated web pages which also needed to be considered.
For a quick overview I like the file size format xxx.x fooB where foo the biggest applicable of T, G, M, k (or empty).
That is, divide numBytes by 1024 until it's < 1000 using floating point arithmetic. Remember how often you divided, convert that to the according foo.
Of course you might want to consider other formats for detailed file size information.

Resources