I am trying to get my console to print out a summation of all my Locations rate card pricing.
I am trying to complete this task through the console but getting a BigDecimal as the result. Stuck on how to convert this result into a legible string or integer.
Results:
Location.pluck(:rate_card).sum
=> "#<BigDecimal:7f7cf347edd0,'0.3091675E6',18(36)>"
In my Location 'index', to be able to see a dollar amount, I have this setup as:
<%= number_to_currency(location.rate_card, :precision => 2) %>
TIA
Location.each do |e|
puts e.rate_card.to_s.to_f.round(2)
end
You're seeing :rate_card returned as a BigDecimal because that's how it's defined in your database schema. If you were to issue Location.rate_card.class in a Rails console you'll see => BigDecimal.
As was mentioned by #Darby, you can use round. In a console, issue Location.pluck(:rate_card).sum.round(2) and that should show the desired result rounded properly.
Lastly, is there significance to the second part of your results? You show the code you're using to display the view code properly but I don't think it has bearing on your question.
A BigDecimal can be converted to a string like this.
pry(main)> b = BigDecimal.new('78.23')
=> #<BigDecimal:7ff0119cab68,'0.7823E2',18(18)>
[37] pry(main)> b.to_s
=> "0.7823E2"
You don't need to change this to a string first and then a float.
to_f is defined on a BigDecimal object.
[34] pry(main)> b.to_f
=> 78.23
There is also to_i and to_r for integers and rationals respectively.
Related
Say I have a GRPC order that looks like this when generated:
Google::Protobuf::DescriptorPool.generated_pool.build do
add_message "something.Order" do
optional :uuid, :string, 1
repeated :shipments, :message, 2, "something.Shipment"
...
end
end
So an Order has many shipments. When I create the order to send back as a response in the service... how do I create the many shipments?
Can I just do:
order = Order.find(request.id)
Something::Order.new(uuid: order.id, shipments: [order.shipments)
Or does it needs to be:
order = Order.find(request.id)
Something::Order.new(uuid: order.id, shipments: [order.shipments.attributes)
I get the latter from these docs
I'm not sure but it looks like the google-protobuf package is used here?
(https://github.com/google/protobuf).
If that's the case, I don't think the ruby-protobuf docs are relevant here.
For using Google::Protobuf here, it looks like you should be able to add an array of Shipment objects to the 'shipments' field of an 'Order' instance.
I'd like to avoid TIMESTAMP columns in my schema and use DATETIME instead because of the limited range of the former (see Year 2038 problem). Therefore, I defined my column like this
def valueDate = column[LocalDateTime]("VALUE_DATE", SqlType("DateTime"))(localDateTimeColumnType)
and provided an implicit mapping (I got it somewhere from the web):
implicit val localDateTimeColumnType = MappedColumnType.base[LocalDateTime, Timestamp](
d => Timestamp.from(d.toInstant(ZoneOffset.ofHours(0))),
d => d.toLocalDateTime
)
This works, but by using java.sql.Timestamp I still suffer from the limited range, even if my DB column is a DATETIME. I tried to use a String based mapping, but it does not work:
implicit val localDateTimeColumnType = MappedColumnType.base[LocalDateTime, String](
d => d.format(DateTimeFormatter.ofPattern("YYYY-MM-DD HH:MM:SS")),
d => LocalDateTime.parse(d, DateTimeFormatter.ofPattern("YYYY-MM-DD HH:MM:SS"))
)
For some reasons, the insert statement fails (the Futures onFailure callback is called). I wonder how a working range-preserving mapper would look like. Any ideas?
Ok Lesson #1: Read the error message.
After learning how to display exception messages in play callbacks I got this:
Field DayOfYear cannot be printed as the value 157 exceeds the maximum print width of 2
It turned out that my DateTime format is rubbish. As one can read here, the format has to be yyyy-MM-dd HH:mm:ss instead of YYYY-MM-DD HH:MM:SS. The correct mapping looks like this:
implicit val localDateTimeColumnType = MappedColumnType.base[LocalDateTime, String](
d => d.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
d => LocalDateTime.parse(d, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
)
EDIT: I accidentally misrepresented the problem when trying to pare-down the example code. A key part of my code is that I am attempting to sort the array after adding elements to it. The hang appears on sort, not insert. The following abstracted code will consistently hang:
<?=
local('a' = array)
#a->insert('test1' = map('a'='1'))
#a->insert('test2' = map('b'='2')) // comment-out to make work
#a->sort
#a
?>
I have a result set for which I want to insert a pair of values into an array for each unique key, as follows:
resultset(2) => {
records => {
if(!$logTypeClasses->contains(field('logTypeClass'))) => {
local(i) = pair(field('logTypeClass'), map('title' = field('logType'), 'class' = field('logTypeClass')))
log_critical(#i)
$logTypeClasses->insert(#i) // Lasso hangs on this line, will return if commented-out
}
}
}
Strangely, I cannot insert the #i local variable into thread variable without Lasso hanging. I never receive an error, and the page never returns. It just hangs indefinitely.
I do see the pairs logged correctly, which leads me to believe that the pair-generating syntax is correct.
I can make the code work as long as the value side of the pair is not a map with values. In other words, it works when the value side of the pair is a string, or even an empty map. As soon as I add key=value parameters to the map, it fails.
I must be missing something obvious. Any pointers? Thanks in advance for your time and consideration.
I can verify the bug with the basic code you sent with sorting. The question does arise how exactly one sorts pairs. I'm betting you want them sorted by the first element in the pair, but I could also see the claim that they should be sorted by last element in the pair (by values instead of by keys)
One thing that might work better is to keep it as a map of maps. If you need the sorted data for some reason, you could do map->keys->asArray->sort
Ex:
local(data) = map('test1' = map('a'=2,'b'=3))
#data->insert('test2' = map('c'=33, 'd'=42))
local(keys) = #data->keys->asArray
#keys->sort
#keys
Even better, if you're going to just iterate through a sorted set, you can just use a query expression:
local(data) = map('test1' = map('a'=2,'b'=3))
#data->insert('test2' = map('c'=33, 'd'=42))
with elm in #data->eachPair
let key = #elm->first
let value = #elm->second
order by #key
do { ... }
I doubt you problem is the pair with map construct per se.
This test code works as expected:
var(testcontainer = array)
inline(-database = 'mysql', -table = 'help_topic', -findall) => {
resultset(1) => {
records => {
if(!$testcontainer->contains(field('name'))) => {
local(i) = pair(field('name'), map('description' = field('description'), 'name' = field('name')))
$testcontainer->insert(#i)
}
}
}
}
$testcontainer
When Lasso hangs like that with no feedback and no immediate crash it is usually trapped in some kind of infinite loop. I'm speculating that it might have to do with Lasso using references whenever possible. Maybe some part of your code is using a reference that references itself. Or something.
I am working in C# with ASP.NET. I am familiar with this error but this time I can't solve it.
I have text in a drop-down list like this:
राम कुमार सिंह 8s2w8r
here राम कुमार सिंह is the name in HINDI while 8s2w8r is users' ID.
I need to separate these two values and need to pass them as session variables. The logic I am using is depicted in the code.
public string reverse(string s)
{
char []temp=s.ToCharArray();
Array.Reverse(temp);
return (temp.ToString());
}
string dropdowntextreversed=reverse(DropDownList1.Text);
char []delim=new char[]{' '};
string []parts=dropdowntextreversed.Split(delim,2);
string family_head_uid = reverse(parts[0]);
string family_head = reverse(parts[1]);
Session.Add("family_head", family_head);
Session.Add("family_head_uid", family_head_uid);
Response.Redirect("/WebForm1.aspx");
I always get an error as the index was outside the bounds of the array! I don't understand this because I am breaking the string into 2 parts so it should have parts[0] and parts[1]. Please suggest...
You are splitting the string into MAXIMUM 2 parts, but if there's only one you will get probably one part.
Read this documentation
Try to assert that parts.Length is == 2 or to access elemnts only there atre two elements
Try this link. As I think there is a problem in the temp.ToString() which will return System.Char[] rather than the value which are you looking for. Use string.join instead will work.
Use the following reverse method:
public string reverse(string s)
{
return String.Join(String.Empty, s.ToCharArray().Reverse());
}
Afternoon all.
A very simple one for you today from thicky Rich.
I have a label I want to display as a lovely number format i.e. {0:N0}
Now, this label text equates to a query string value.
How do I go about formatting a label's text from a query string value in one fell swoop?
I have tried this
lblTotalPurchQS.Text = String.Format("{0:N0}",Request.QueryString["totalpurchasequantity"].ToString());
but with little success.
Any ideas or pointers?
Don't use ToString on the incoming query string parameter, but convert it to an int first:
lblTotalPurchQS.Text = String.Format("{0:N0}", int.Parse(Request.QueryString["totalpurchasequantity"]));
Note:
The above is not safe code. First, the conversion may fail with a conversion exception. You should also be HTML escaping the output, in case of XSS.
This is better:
int totalPurchaseQuantity;
if(int.TryParse(Request.QueryString["totalpurchasequantity"], out totalPurchaseQuantity))
{
lblTotalPurchQS.Text = Server.HtmlEncode(String.Format("{0:N0}", totalPurchaseQuantity);
}