In Vaadin 7, is there an easy way to calculate the numeric total for selected columns? I know how to do it for Vaadin 8, defined here. But since Vaadin 7 uses a container, I am trying to think of the best way to do it. Currently, this is the best way I can think of, based on the documentation here. Code is a rough draft, so I expect there are some syntax problems. Treat it more as pseudo code, if possible.
Map<Object,Double> totals = new HashMap();
for (Iterator<?> i = container.getItemIds().iterator(); i.hasNext();) {
Object itemId = i.next();
Item item = container.getItem(itemId);
for(Object totalCol : totalColumns)
{
Object columnVal = item.getItemProperty(totalCol);
Double total = totals.get(totalCol);
if(!(total instanceof Double))
total = 0.0;
if(columnVal instanceof Double)
{
total += (Double)columnVal;
}
else if(columnVal instanceof Long)
{
total += (Long)columnVal;
}
else if(columnVal instanceof Integer)
{
total += (Integer)columnVal;
}
else if(columnVal instanceof String)
{
try {
Long value = Long.parseLong((String) columnVal);
total += value;
} catch (NumberFormatException e) {
try {
Double value = Double.parseDouble((String) columnVal);
total += value;
} catch (NumberFormatException e1) {
}
}
}
totals.put(totalCol, total);
}
/* At this point, go through totals Map, and set value to correct footer column with correct
* text formatting. This part is easy, and clearly documented, so leaving it off this
* code example.
*/
}
By the way, the above idea works, my question is more if this is the best idea or not?
Related
I'm working through an exercise from this course. This code:
void main() {
const order = ['pepperoni', 'margherita', 'pineapple'];
print("Total: ${calculateTotal(order)}");
}
double calculateTotal(List<String> order) {
var total = 0.0;
const pizzaPrices = {
'margherita': 5.5,
'pepperoni': 7.5,
'vegetarian': 6.5,
};
for (var item in order) {
if (pizzaPrices[item]!=null) {
total += pizzaPrices[item];
}
}
return total;
}
Produces the error message The argument type 'double?' can't be assigned to the parameter type 'num'. pointing to the line total += pizzaPrices[item];
total += pizzaPrices[item]! compiles as expected, without errors.
I don't understand why the compiler would need the !, since it already knows pizzaPrices[item] cannot be null.
The reason is that the [] operator on Map is defined to return a nullable type since if the element you search for are not in the map, the [] operator will return null.
It might look obvious to you, but the compiler cannot know for sure that just because you checked the returned value from pizzaPrices[item] once, it will return the same value again the second time you ask (e.g. in some custom made Map implementation).
A solution is instead to save the value in a local variable which you can then check for null. Dart will in this case promote the variable as expected:
void main() {
const order = ['pepperoni', 'margherita', 'pineapple'];
print("Total: ${calculateTotal(order)}");
}
double calculateTotal(List<String> order) {
var total = 0.0;
const pizzaPrices = {
'margherita': 5.5,
'pepperoni': 7.5,
'vegetarian': 6.5,
};
for (var item in order) {
final pizzaPrice = pizzaPrices[item];
if (pizzaPrice != null) {
total += pizzaPrice;
}
}
return total;
}
I am new to programming and today I wanted to try out the LeetCode problem 234. Palindrome Linked List:
Given the head of a singly linked list, return true if it is a palindrome or false otherwise.
Example 1:
Input: head = [1,2,2,1]
Output: true
but I couldn't even manage the first problem.
I first tried to convert the linked list to a string and compare like:
String[i] == String[length-i-1]
which worked for small lists but not for the gigantic test list where I got:
Time Limit Exceeded
In my second attempt I used recursion like this:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode? next;
* ListNode([this.val = 0, this.next]);
* }
*/
class Solution {
bool isPalindrome(ListNode? head) {
ListNode? current = head;
while(current?.next != null)
current = current?.next;
if (current?.val != head?.val)
return false;
else{
current = null;
isPalindrome(head?.next);
}
return true;
}
}
This also works with small lists, but for the test list I get a run time error:
Stack overflow
I wonder where this issue comes from.
Is it due to the maximum number of nested calls? And where can I find the recursion depth of Dart?
Or is there just a way simpler solution for this?
There are several issues with your attempt:
current = null will only set that variable to null. It does not affect the list. If you want to remove the last element from the list, you'll need access to the node that precedes it, and set its next property to null.
The boolean that the recursive call returns is always ignore. Instead execution continues with the return true statement, which will lead to incorrect results (when false was expected).
Before mentioning another problem, here is the correction for your algorithm:
bool isPalindrome(ListNode? head) {
ListNode? current = head;
ListNode? prev = null;
while(current?.next != null) {
prev = current; // follow behind current
current = current?.next;
}
if (current?.val != head?.val)
return false;
else if (prev == null)
return true; // List has only one node
else {
prev?.next = null; // Detach the tail node
return isPalindrome(head?.next); // Return the recursive result!
}
}
This will do the job correctly, but it is too slow. At every level of recursion almost all of the same nodes are iterated again (with that while loop), so for a list with 100 nodes, there are 100+98+96+94+...+2 iterations. In other words, the time complexity of this algorithm is quadratic. You'll need a different idea for the algorithm.
One idea for an efficient algorithm that doesn't require extra O(n) space, is to:
find the middle node of the list. You can for instance first determine the length of the list with a first iteration, and then in a second iteration you can stop half way.
reverse the second half of the list, giving you two shorter lists. Here you could use recursion if you wanted to.
and then compare those two lists node by node.
There are several Q&A on this algorithm, also on this site, so I'll leave that for your further research.
If you cannot make it work, here is a solution (spoiler!):
class Solution {
int listSize(ListNode? head) {
int size = 0;
while(head?.next != null) {
head = head?.next;
size++;
}
return size;
}
ListNode? nodeAt(ListNode? head, int index) {
while(head?.next != null && index > 0) {
head = head?.next;
index--;
}
return index == 0 ? head : null;
}
ListNode? reverse(ListNode? head) {
ListNode? prev = null;
ListNode? next;
while (head != null) {
next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
}
bool isEqual(ListNode? head1, ListNode? head2) {
// Only compares the nodes that both lists have:
while (head1 != null && head2 != null) {
if (head1.val != head2.val) return false;
head1 = head1.next;
head2 = head2.next;
}
return true;
}
bool isPalindrome(ListNode? head) {
return isEqual(head, reverse(nodeAt(head, listSize(head) >> 1)));
}
}
I can't quite understand your recursion solution without pointers. I solved it using a list. It is not the best solution but is simple.
// Definition for singly-linked list.
// class ListNode {
// int val;
// ListNode? next;
// ListNode([this.val = 0, this.next]);
// }
class Solution {
bool isPalindrome(ListNode? head) {
List<int> stack = [];
ListNode? p = head;
while (p != null) {
stack.add(p.val);
p = p.next;
}
print(stack);
bool isP = true;
while(head!.next!=null&&isP){
var a = stack.removeLast();
print('removed $a');
print('head val ${head.val}');
isP = head.val==a;
head=head.next!;
}
return isP;
}
}
The problem with your solution is
After a while loop current is rightmost node in the list
while (current?.next != null) {
current = current?.next;
}
comparing leftmost and rightmost node of LinkedList
if (current?.val != head?.val)
return false;
Start over with head shifted one place to the right
else {
current = null;
isPalindrome(head?.next);
}
But current is still rightmost node after a while loop
while (current?.next != null) {
current = current?.next;
}
And this will return false
if (current?.val != head?.val)
{
return false;
}
After second recursion program exits returning true
I'm new to Dart. I'm calculating the price of a pizza order. In my current solution, I'm using the assertion operator. What do you think about it?
I've read many times that you shouldn't use it. Do you think my code is ok, or would you do something better/different?
void main() {
const List<String> order = ['margherita', 'pepperoni', 'pineapple'];
calcTotalPrice(order: order);
}
calcTotalPrice({required List<String> order}) {
final Map<String, double> pizzaPrices = {
'margherita': 5.5,
'pepperoni': 7.5,
'vegetarian': 6.5
};
double total = 0.0;
for (var item in order) {
pizzaPrices[item] ??= 0.0;
total += pizzaPrices[item]!; // assertion operator (!)
}
print(total);
}
Your code is fine but you can avoid collecting unknown keys in the map pizzaPrices with:
for (var item in order) {
total += pizzaPrices[item] ?? 0.0;
}
I have a list of big records and I need to loop through each record, add some filter and calculation and add it to my another list. I think doing one by one is affecting the performance because it's taking like 12s to show 900 records.
I am unable to identify why it's taking too long. I used my chrome developer tool to identify where it's slow. Then I came to find out loading taking 0.2s, scripting taking 3s, rendering taking 3s, idle is 3s and others are two seconds.
Maybe I am using Entity Framework and DataTables is making it slow. Or maybe something wrong is with my query. Following is my code:
public ActionResult Index(int id, string language)
{
var All_Employees = from employee in db.Employees
.Include(x => x.Country).Include(x => x.Status)
where enployee.GenderId == id
select employee ;
var List = new List<EmployeeListViewModel>();
foreach(var Record in All_Employees.ToList()
.OrderByDescending(x=> ParseDate(x.JoiningDate)))
{
EmployeeListViewModel item = new EmployeeListViewModel();
item.Id = Record.Id;
item.Code = Record.Code;
if(Record.CountryId != null)
{
if(language == "en")
{
item.Country = Record.Country.NameE;
}
else
{
item.Country = Record.Country.NameA;
}
}
item.Date = Record.JoiningDate;
int WorkingDays = 0;
if(Record.JoiningDate != null)
{
DateTime Joining= Convert.ToDateTime(ParseDate(Record.Record.JoiningDate));
TimeSpan t = DateTime.Now.Date - Joining;
int Days = int.Parse(t.TotalDays.ToString());
if (Days > 0)
{
WorkingDays = Days;
}
}
item.Days = WorkingDays.ToString();
if (Record.StatusId != null)
{
if (language == "en")
{
item.Status = Record.Status.NameE;
}
else
{
item.Status = Record.Status.NameE;
}
}
List.Add(item);
}
return View(List);
}
Another reason could be I am converting my date:
private static DateTime? ParseDate(string dateString)
{
if(dateString != null)
{
return DateTime.ParseExact(dateString, "dd-MM-yyyy", CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.None);
}
else
{
return null;
}
}
I don't want to make date filed as DateTime in my database, due to some reasons.
What's the best way to improve performance in my current situation?
Too much casting is used here in your code and list is created twice. One way you can do code like below.
List<EmployeeListViewModel> lstData = EmployeeListViewModel.ToList();
for(int i = 0; i < lstData.Count; i++)
{
//Put logic here for required changes like Language and Date.
if(lstData[i].CountryId != null)
{
if(language == "en")
lstData[i].Country = lstData[i].Country.NameE;
else
lstData[i].Country = lstData[i].Country.NameA;
}
}
Try to reduce casting specially for string and date-time. Below is example.
int Days = int.Parse(t.TotalDays.ToString());
In above line t.TotalDays is always int type, no need to cast to string and int again.
public List<Forest> getForest(int limit, int offset) {
try {
return newArrayList(ao.find(Forest.class, Query.select().order("ID DESC").limit(limit).offset(offset)));
} catch (Exception e) {
return null;
}
}
The above code working fine, but its not return total number of rows.
So i unable to apply last page index.
I have applied First, Next & Previous
I guess you need to "count" your records:
Query query = Query.select().order("ID DESC");
int count = ao.count(Forest.class, query);