I have a view helper that totals the items inside line items. Each order can have many line items. Each line item has different sizes inside it (the fields). For this below I'm curious how to sum up a certain field for multiple line items.
def total_items(order)
xxs = order.lineitems.xxs.sum
return xxs
end
This is what I have but doesn't work when there are multiple line items for an order, how can I properly write it?
It is not very obvious what you are asking, but I think what you want is something like this:
def total_items(order)
order.lineitems.inject(0) { |total, line_item| total + line_item.xxs }
end
What this method does, is similar to this:
def total_items(order)
total = 0;
order.lineitems.each do |line_item|
total += line_item.xxs
end
total
end
By the way, in Ruby the return keyword is optional.
Related
I have a dataframe which has a column called hexa which has hex values like this. They are of dtype object.
hexa
0 00802259AA8D6204
1 00802259AA7F4504
2 00802259AA8D5A04
I would like to remove the first and last bits and reverse the values bitwise as follows:
hexa-rev
0 628DAA592280
1 457FAA592280
2 5A8DAA592280
Please help
I'll show you the complete solution up here and then explain its parts below:
def reverse_bits(bits):
trimmed_bits = bits[2:-2]
list_of_bits = [i+j for i, j in zip(trimmed_bits[::2], trimmed_bits[1::2])]
reversed_bits = [list_of_bits[-i] for i in range(1,len(list_of_bits)+1)]
return ''.join(reversed_bits)
df['hexa-rev'] = df['hexa'].apply(lambda x: reverse_bits(x))
There are possibly a couple ways of doing it, but this way should solve your problem. The general strategy will be defining a function and then using the apply() method to apply it to all values in the column. It should look something like this:
df['hexa-rev'] = df['hexa'].apply(lambda x: reverse_bits(x))
Now we need to define the function we're going to apply to it. Breaking it down into its parts, we strip the first and last bit by indexing. Because of how negative indexes work, this will eliminate the first and last bit, regardless of the size. Your result is a list of characters that we will join together after processing.
def reverse_bits(bits):
trimmed_bits = bits[2:-2]
The second line iterates through the list of characters, matches the first and second character of each bit together, and then concatenates them into a single string representing the bit.
def reverse_bits(bits):
trimmed_bits = bits[2:-2]
list_of_bits = [i+j for i, j in zip(trimmed_bits[::2], trimmed_bits[1::2])]
The second to last line returns the list you just made in reverse order. Lastly, the function returns a single string of bits.
def reverse_bits(bits):
trimmed_bits = bits[2:-2]
list_of_bits = [i+j for i, j in zip(trimmed_bits[::2], trimmed_bits[1::2])]
reversed_bits = [list_of_bits[-i] for i in range(1,len(list_of_bits)+1)]
return ''.join(reversed_bits)
I explained it in reverse order, but you want to define this function that you want applied to your column, and then use the apply() function to make it happen.
I have records in the stock.move table that has One2many relation to stock.move.reconcile with column move_to_id which is the ID of another record in stock.move table. So this chain can be thousands of records.
As you can see in my example I loop trough all records and go down tier by tier, but as I said before there could be thousands of linked records so my approach will not work here.
I do know that probably I need to use a while loop here, something like while there is move_to_ids, then I should loop through records and keep adding IDs to list, but I just can't figure it out how to do it.
move1(stock.move ID = 10) record that has One2many relation with 2 records inside: move_to_ids (stock.move.reconcile)
each of move_to_ids has move_to_id(many2one, 'stock.move' ID = 11)
each of this move_to_id(stock.move, ID=11) records have again any number of move_to_ids (stock.move.reconcile) and each of thismove_to_idsrecords havemove_to_id('stock.move', ID=12)` and so on.
So basically I want to add to list all move_to_id IDs 10, 11, 12, etc. to list for all related move_to_ids.
moves_to_recalculate = [10,11,12] and so on until when there is 0 move_to_ids to get move_to_id from.
class StockMove(models.Model):
_name = 'stock.move'
move_to_ids = fields.One2many(
'stock.move.reconcile', 'move_from_id', string='Move to')
move_from_ids = fields.One2many(
'stock.move.reconcile', 'move_to_id', string='Move From'
)
class StockMoveReconcile(models.Model):
_name = 'stock.move.reconcile'
_description = 'Stock Move Reconcile'
move_to_id = fields.Many2one('stock.move', string='Move To')
move_from_id = fields.Many2one('stock.move', string='Move From')
def recalculate(self):
moves = self.browse(('active_ids'))
moves_to_recalculate = []
for move1 in moves:
#I add my first move in chain to list
moves_to_recalculate.append(move1.id)
#First move have 2 moves_to_ids so i make another loop to add it ID to list
for second_tier_move in move.move_to_ids:
moves_to_recalculate.appen(second_tier_move.move_to_id.id)
# secont tier move has 1 move_to_ids so i do another loop, and add it's ID to list.
for third_tier_move in second_tier_move.move_to_ids:
moves_to_recalculate.appen(third_tier_move.move_to_id.id)
#third_tier_move has another move_to_ids , and so on.
I got answer from other resource but I think i need to post it here because the answer is excellent.
def recalculate_fifo(self):
moves = self.browse(self._context.get('active_ids'))
moves_to_recalculate = moves
current_moves = moves
while current_moves:
current_moves = current_moves.mapped('move_to_ids.move_to_id')
current_moves -= moves_to_recalculate
moves_to_recalculate |= current_moves
I work in a warehouse, and I'm using Google Sheets to keep track of inventory. Adding and subtracting is easy, but I've been tasked with creating a "reserve" system:
A number of pieces of stock are reserved for upcoming jobs. When that stock is ordered and received, the reserve quantity is "satisfied" and decreases by the number of pieces received. The problem with setting it up just like the ADD and SUBTRACT function is that not all stock received is "reserved", and my RESERVE totals end up being "-57", "-72", "-112", etc.
I have a large dataset of form responses logged in four columns: Timestamp, Item ID#, Action (ADD, SUBTRACT, or RESERVE), and QTY. What I'm looking for is a way to create a running tally in column E for each unique Item ID#, using the values in column D "QTY". I need for any value <0 to return "0".
Example Sheet
I've been able to create a running tally formula that satisfies my conditions for one Item ID# at a time. To avoid creating a separate column for each Item ID#, though, I need to figure out how to apply it separately to each unique Item ID#, and array it down Column E so each new form response is calculated automatically.
=if(C2="RESERVE",E1+D2,if(and(C2="ADD",(E1+D2)<0),0,E1+D2))
The closest thing to a solution I've been able to find is a script created by user79865 for this question titled: "Running Total In Google Sheets with Array". Unfortunately, trying to plug this into Google Sheets Script Editor gives me an error popup:
TypeError: Cannot read property "length" from undefined. (line 2, file "runningtotal")
I have no programming background and never dreamed I'd be looking at code just to make a running tally.
If anybody can offer any insight into this, fixing or replacing the script or offering an ARRAYFORMULA solution, I'd really appreciate it!
function runningTotal(names, dates, amounts) {
var sum, totals = [], n = names.length;
if (dates.length != n || amounts.length != n) {
return 'Error: need three columns of equal length';
}
for (var i = 0; i < n; i++) {
if (names[i][0]) {
sum = 0;
for (var j = 0; j < n; j++) {
if (names[j][0] == names[i][0] && dates[j][0] <= dates[i][0]) {
sum = sum + amounts[j][0];
}
}
}
else {
sum = '';
}
totals.push([sum]);
}
return totals;
}
I am trying to increment twice in a loop and print the OrientRecord Objects using Python.
Following is my code -
for items in iteritems:
x = items.oRecordData
print (x['attribute1'])
y=(next(items)).oRecordData #Here is the error
print (y['attribute2'])
Here, iteritems is a list of OrientRecord objects. I have to print attributes of two consecutive objects in one loop.
I am getting the following error -
TypeError: 'OrientRecord' object is not an iterator
Try using a different approach to it:
for i in range(0,len(iteritems),2):
x = iteritems[i].oRecordData
print (x['attribute1'])
y = iteritems[i+1].oRecordData
print (y['attribute2'])
The range() function will start from 0 and iterate by 2 steps.
However, this will work properly only if the total amount (range) of records is an even number, otherwise it'll return:
IndexError: list index out of range
I hope this helps.
I have an array called #friend_comparisons which is populated with a number of user objects. I then sort the array using the following:
#friend_comparisons.sort! { |a,b| b.completions.where(:list_id => #list.id).first.counter <=> a.completions.where(:list_id => #list.id).first.counter }
This is sorting the array by a certain counter associated with each user (the specifics of which are not important to the question).
I want to find out how many user objects in the array have a counter that is greater than a certain number (let's say 5). How do I do this?
Here is how I am currently solving the problem:
#friends_rank = 1
for friend in #friend_comparisons do
if friend.completions.where(:list_id => #list.id).first.counter > #user_restaurants.count
#friends_rank = #friends_rank + 1
end
end
You can use Array#count directly.
#friend_comparisons.count {|friend| friend.counter >= 5 }
Docs: http://ruby-doc.org/core-2.2.0/Array.html#method-i-count
(same for ruby 1.9.3)
Array#select will get the job done.
Docs: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-select
You might do something like this:
number_of_users = #friend_comparisons.select{|friend| friend.counter >= 5 }.size