Django Admin show value to 2 decimal places - django-admin

I need to control how many decimal places of a value are shown in the Django admin. So far I can only find documentation for database representations. Could you please point me in the right direction?

After some research, I have found that Django does not offer built in control over float output precision. I simply had to write a function that controls the output of the value and specify how it is returned, i.e:
def some_output(self, obj):
return "%.xf" % obj.to_display
Where "x" is the precision and "to_display" is the value from the db.

Related

Delphi - comparison of two "Real" number variables

I have problem with comparison of two variables of "Real" type. One is a result of mathematical operation, stored in a dataset, second one is a value of an edit field in a form, converted by StrToFloat and stored to "Real" variable. The problem is this:
As you can see, the program is trying to tell me, that 121,97 is not equal to 121,97... I have read
this topic, and I am not copletely sure, that it is the same problem. If it was, wouldn't be both the numbers stored in the variables as an exactly same closest representable number, which for 121.97 is 121.96999 99999 99998 86313 16227 83839 70260 62011 71875 ?
Now let's say that they are not stored as the same closest representable number. How do I find how exactly are they stored? When I look in the "CPU" debugging window, I am completely lost. I see the adresses, where those values should be, but nothing even similar to some binary, hexadecimal or whatever representation of the actual number... I admit, that advanced debugging is unknown universe to me...
Edit:
those two values really are slightly different.
OK, I don't need to understand everything. Although I am not dealing with money, there will be maximum 3 decimal places, so "currency" is the way out
BTW: The calculation is:
DATA[i].Meta.UnUsedAmount := DATA[i].AMOUNT - ObjQuery.FieldByName('USED').AsFloat;
In this case it is 3695 - 3573.03
For reasons unknown, you cannot view a float value (single/double or real48) as hexadecimal in the watch list.
However, you can still view the hexadecimal representation by viewing it as a memory dump.
Here's how:
Add the variable to the watch list.
Right click on the watch -> Edit Watch...
View it as memory dump
Now you can compare the two values in the debugger.
Never use floats for monetary amounts
You do know of course that you should not use floats to count money.
You'll get into all sorts of trouble with rounding and comparisons will not work the way you want them too.
If you want to work with money use the currency type instead. It does not have these problems, supports 4 decimal places and can be compared using the = operator with no rounding issues.
In your database you use the money or currency datatype.

Filemaker if dropdown contains text alter calculation

I am fairly sure stuff like this has been answered but I am losing my hair at the moment with this. I am using Filemaker Pro 13
I have been landed with the job of updating some templates, I have done this before but all I was doing was updating the visual side of things. Now I am wanted to dynamically update some labels and calculations depending on a 'Company selected(drop down with custom values that are all text).
Currently all costs are multiplied by 2. So if original cost = $4 then customer cost is $8. However if 'Company 4' is selected rather than being multiplied by 2 it needs to be multiplied by 1.5.
I currently have two functions that I am trying to use this functionality on a field box.
First function:
If (Company: = "Comp4"; 1;0)
Second function:
If (${Function1}; ${$Cost}*1.5; ${$Cost}*2 )
This does not work, hence the answering of this question. As far as I could understand if statements work as (Condintion; If true do X; Else do Y;). This may be the problem? I do come from a programming background but this program is irritating me beyond belief at the moment.
If this has been answered before then I offer my sincerest apologies.
Thank you for any answers or help pointing me into the right direction.
Edit: Just tried this:
If (ValueCount(FilterValues(Company;"Comp4"));${$Cost}*1.5; ${$Cost}*2)
This was to no avail. Ideally if I could fit this into one function that would be great but so far I am still failing.
Edit 2:
With regards to the function / functions not working. I would often only get the ${$Cost}*2 side of things would happen however the ${$Cost}*1.5 would not even when "Comp4" was selected. This made me think that it was either the system was not detecting "Comp4" was selected or I need to look elsewhere to find the value I need to look at.
Edit 3: Real values and calculations used
Currently used and working so to speak ( Just does the *2 aspect of things)
Field Name: x2$Charges
Calculation: ${$Charges}*2. - $Charges is the 'cost' fields (10 of them).
What I want to do is when a specific company is selected rather than doing cost *2 I want to do cost *1.5.
The check for said company is :
Field Name: x2CheckSSL
Calculation: If(Sales Rep.|Distributor: = "SSL";1.5;2)
Where Sales Rep.|Distributor: is 'Company'
It's difficult to tell what is wrong with your syntax, because we don't know the exact names of your fields. Also, "this does not work" is not a good description of a problem.
The fact that you have constructs like ${$Cost} indicates that you have invalid field names.
If you had fields named Company and Cost, then a calculation field (defined in the same table as these two fields) =
If ( Company = "Comp4" ; 1.5 ; 2 ) * Cost
should provide the expected result.
On a more general level, this is not a good approach to take. All of these factors {"Comp4", 1.5, 2} are data and should not be hard-coded into a calculation formula.
Properly, every company should have a markup value stored in its own record, and this would be looked up into a field when you select a company. Alternatively, only some (preferred) companies would have a markup, while others would use a default value stored in a preferences table.
In addition, the Company field in this table (Invoices?) should really be CompanyID and store only the (meaningless) ID of the selected company.
Added:
This is a suggestion how to perform a quick fix to your current problem, following the clarifications made in comments.
The following fields are being assumed:
• $Charges - Number[10]
• Sales Rep.|Distributor: - Text
• x2$Charges - Calculation[10] = [see formula below]
Change the calculation formula of x2$Charges to =
If ( Extend (Sales Rep.|Distributor: ) = "SSL" ; 1.5 ; 2 ) * ${$Charges}
There is no need for the x2CheckSSL field.
IMPORTANT:
You should not use repeating fields for this. I suggest that as soon as possible you rewrite your solution and fix the flaws dscovered here, namely:
Rename your fields to valid (and reasonable*) names ;
Convert repeating fields to records in a related table;
Use lookups instead of hard-coding data in calculations.
(*) e.g. not names that end with ":"
IF statement works exactly as you described and I do not see why you need two different functions. I do not understand your syntax - ${$Cost}. Are you trying to add "$" to your output?
Let's say you have a field for selection as "slelect_company" in Companies table/layout and you stored cost in a variable called $cost
You calculation will be:
If (Companies::slelect_company = "Comp4"; $Cost*1.5; $Cost*2 )
If you set the field to output result, use formatting to add $ sign
If you set the label on the layout to show the output, use this:
If (Companies::slelect_company = "Comp4"; "$" & $Cost*1.5; "$" & $Cost*2 )
If you have more than one check, you can use Case - similar to switch in the other languages
Rather than putting your calculation in a function try creating a new calculation field and put your calculation there. When the record is committed you will see the value of this calculation field change and you will know if your function is working.
To do this
Go to File->Manage->Database
Type in a new field name and select "calculation" as the type and press create.
Enter your calculation e.g. if(Companies::select_company = "Comp4"; Companies::Cost * 1.5; Companies::Cost * 2)
The calculation engine will tell you what the errors are when you try to press okay after typing the calculation.
If it never detects the condition "Comp4" then there is an error in your string comparison, perhaps a trailing space, or an uppercase character or similar.

Converting string to float or decimal sometimes results in long precision

I have a string which I want to convert to a decimal.
eg.
tax_rate = "0.07"
tax_rate.to_d
In most cases it converts to 0.07 but sometimes it converts it to 0.07000000000000001. Why?
If it helps, when I look at the log of when I insert this value into the DB, this is the relevant part:
["tax_rate", #<BigDecimal:7f9b6221d7c0,'0.7000000000 000001E-1',18(45)>]
Hopefully that makes sense to someone.
Disclaimer:
I have a feeling someone is going to ask why I'm doing this.
I've created a simple settings model, where a user can update some global settings.
The Setting model has name, value and var_type columns.
The value column is a string. I use a helper method to retrieve the value in the appropriate format depending on the value of the var_type column.
I cannot explain why but there is a chance I can tell you how to avoid having this kind of trouble when dealing with numbers: use rationals.
Here is the documentation: http://ruby-doc.org/core-1.9.3/Rational.html
As stated, a rational will always give you the exact number you want and thus will avoid rounding errors.
From the doc:
10.times.inject(0){|t,| t + 0.1} #=> 0.9999999999999999
10.times.inject(0){|t,| t + Rational('0.1')} #=> (1/1)
Let me know if this solves your problem. : )

How do I avoid errors when converting strings to numbers if I don't know whether I have floats or integers?

I have stringgrid on delphi form and i am trying to divide values of one cell with value of another cell in another column.
But the problem is, stringgrid cells are populated with different types of numbers, so I am getting ConvertErrors.
For example the numbers in cells can look like
0.37 or 34 or 0.0013 or 0.00 or 0.35 or 30.65 or 45.9108 or 0.0307 or 6854.93.
In another words I never know is it going to be real, float, integer or any other kind of type in those cells.
I have looked everywhere on internet but no luck. Anyone any ideas. By the way I am not exactly Delphi expert. Thanks.
For each string, convert it first to a float value using StrToFloat function in SysUtils.pas . This should allow for any numerical type to be dealt with (unless you have something unusual like complex numbers). As you have some zero values in your list above you should also ensure that you check for divide by zero conditions as this will also potentially throw an exception.
SysUtils has many functions such as TryStrToFloat, TryStrToInt, TryStrToInt64 etc for this purpose. These functions accept a reference parameter (var parameter) for returning the converted value and function itself returns true if the conversion is successful.
If you are sure that the string has a valid number then you can check the input string to see if it has a decimal point before deciding which function to use.
Treat all the numbers as float. Use StrToFloat, divide the numbers, and then convert the result back to string with FloatToStr. If the result is an integer, no decimal point would be produced.

How should I present a cost field to the user, and store it in the database?

Right now I have two fields for cost. One for dollars and one for cents. This works, but it is a bit ugly. It also doesn't allow the user to enter the term "free" or "no cost" if they want. But if I only have one field, I might have to make my parser a bit smarter. What do you think?
On the server side, I combine dollars and cents to store them as decimals in my database. Mainly so that I can gather statistics (cost averages, etc.) quickly.
Do you think it is better to store the cost as a string? Then whenever I actually use the cost for stats or other purposes, I would convert it to a decimal at that point. Or am I on the right track?
There is a rule in database design that states that "atomic data" should not be split. By this rule a price, or cost is such an example of atomic data and therefore it should never be split among multiple columns just like you shouldn't split a phone number among multiple columns (unless you really have a very good reason for it - very rare)
Use a DECIMAL data type. Something like DECIMAL(8,3) should work and it's supported by all ANSI SQL compliant database products!
You can consult Joe Celko's "Thinking In Sets" book for a discussion of this topic. See section 1.6.2, pages 21-22.
EDIT -
It seems from your question that you are also concerned with how to accept user's input in a form that resembles the price (xxxx.xx) - hence the two input boxes, for the whole dollars, and the pennies.
I recommend using a single input box and then doing input validation using Regular Expressions to match your format (i.e. something like [0-9]+(.[0-9]{1,3})? would probably work but could be improved). You could then parse the validated string to a Decimal type in your language, or just pass it as a string into your database - SQL will know how to cast it to a DECIMAL type.
Keep the whole cost as decimal. If it's free, then keep the cost as 0. In presentation if cost is zero - write "free" instead of 0.
I generally store the cost as the lowest unit (pennies) and then convert it to whole dollars later.
So a cost of $4.50 gets stored as 450. Free items would be -1 pennies. You could store free things as 0 pennies as well, this gives you the flexibility to use 0 and -1 to mean two slightly different things (free vs no sale?).
It also makes it easier to support countries that don't use cents if you choose to go that route.
As for presenting the data entry field, I personally don't like it when I have to keep switching fields for tiny things (like when they break up phone numbers into 3 fields, or IP addresses into 4). I'd present one field, and let the users type the decimal point in themselves. That way, your users don't have to tab (or click, if they are unfamiliar with tab) to the next field.
Use cents, use 450 for $4.50 this will save you problems that are arising very often
from the fact that floating point operations are not safe. Just try the following expression in irb:
0.4 - 0.3 == 0.1 will return false. All because of floating point representation
innacuracies.
In my models I'm always using:
attr_accessor :price_with_cents
def price_with_cents
self.price/100.00
end
def price\_with\_cents==(num)
self.price = (num.to_f * 100.00).to_i
end
And the name of column is just price and integer type.
I don't have much experience with decimal columns and their representation in ruby (which can be float that is problematic as i've shown at the begining).
Don't allow garbage to make it to your database. If you're expecting a dollar amount on a field, than make sure it's valid before it gets in there. This will allow you to report better on the data and allow simpler formatting on output.
I suggest making this a single field with validation on update or insert.
if field != SpecialFreeTag then
try to convert to decimal
if fail then report to user
otherwise accept value
Use try parse or regular expressions to help with the validation.
I would store the cost as decimal with the scale being no less than 2 and maybe even 3-5. If something is bought in bulk the unit cost could easily include fractions of a cent. Free items have a cost of 0. If the cost is unknown then allow null values also.

Resources