Django-Python decimal number formatting comma issue - python-3.x

I have a model and there is this decimal field rule;
product_price = models.DecimalField(max_digits=10, decimal_places=2)
I am getting data from an xml file and most of the product prices are like this format;
847.54
So there is actual number after that for the separator from the remainder there is '.' (dot) for it and this is ok.
However some product prices are like this;
2,906.69
The actual number includes an extra comma and this causes a problem. I am getting this error;
django.core.exceptions.ValidationError: ["'2,906.69' value must be a decimal number."]
Should I change my model? or is there any other solution for it?

You can try replacing the comma and then converting the string to float before inserting into DB.
Ex:
def cleanDecimal(value):
return float(value.replace(",", ""))
product_price = models.DecimalField(max_digits=10, decimal_places=2, validators=[cleanDecimal])
Ex:
print(float("2,906.69".replace(",", "")))
2906.69

Related

Mutate: character string is not in a standard unambiguous format

I have a column titled started_at which is formatted in like this: 4/12/2021 18:25. When I try to run code, I get the following message:
Error in mutate():
! Problem while computing day_of_week = wday(start_time, label = TRUE).
Caused by error in as.POSIXlt.character():
! character string is not in a standard unambiguous format
This is the code I am trying to run:
**> cyclistic_trips_merge_v2 %>%
mutate(day_of_week = wday(start_time, label = TRUE)) %>% #creates weekday field using wday()
group_by(usertype, day_of_week) %>% #groups by usertype and weekday
summarise(number_of_rides = n() #calculates the number of rides and average duration
,average_duration = mean(ride_length)) %>% # calculates the average duration
arrange(usertype, day_of_week)**
I am new to R, and this is a capstone project. I get stuck but then figure my way around things doing web searches but right now I am kind of stumped. The date/time mentioned above is classified as a string. I believe that is the problem, but what do I need to convert it to and how can I do that? Can anyone please help? Losing my mind.

Convert varchar string to Currency format in db2 SQL

I have a column from which i have to extract String and then format it back to US currency format with 2 decimal places.
For example :
Column value : {tag}0000020000890|
From this, I have to match the tag and extract 20000890, and format it to 200,008.90
I have extracted the part with below code:
LTRIM(REGEXP_SUBSTR('match pattern', 1,1,'i',,1), '0')
Where match pattern is '\{tag\}(.*?)\|'
With this, I am able to extract 20000890
And then I tried the below to_char and to_number function on top of it to format as comma separated currency with 2 decimal points.
to_char(ltrim(Regexp_substr('match pattern',1,1,'i',1),'0'), '99G999G999D99')
But this throws below error:
Sql error -20447, sqlstate 22007 sqlerrmc 99G999G999D99
Sysibm.Varchar-format
Then I tried,
to_char(to_number(ltrim(Regexp_substr('match pattern',1,1,'i',1),'0')), '99G999G999D99')
But this also throws error:
Sql error -20476, sqlstate 22018 sqlermc DECFLOAT_FORMAT; 99G999G999D99
I'm not sure what causes this error.
The format that you try to use is supported starting from V11.5 only.
TO_CHAR V11.5
TO_CHAR V11.1
Compare the Table 2. Format elements for decimal floating-point to varchar table from both links.
Moreover, you must cast a string to a numeric value in the 1-st parameter of TO_CHAR:
SELECT TO_CHAR(DECFLOAT(REGEXP_SUBSTR(V, '\{tag\}(.*?)\|', 1, 1, 'i', 1)), '99,999,999.99')
FROM (VALUES '{tag}0000020000890|') T(V);
Take a look at VARCHAR_FORMAT. It is the function TO_CHAR is mapped to. The group separator is not G, but "," or ".". Basically, you have to replace your formatting string 99G999G999D99 with something like 99,999,999.99.
The Db2 documentation has more examples on that.

Groovy currency formatting

I'm writing some rows to a text file using groovy (grails 1.3.7) and I want to format the currency like this example output:
$100,000,000.00
$9,123,123.25
$10.20
$1,907.23
So basically right-justified, or left padded, with the dollar sign in front of the number so they all line up like the above. The first number is the longest we would expect to see. Right now I have an amount variable that is simply defined with a def and not string or number or anything specific like that but I can obviously change that if need be. Thanks!
You probably want to use NumberFormat.getCurrencyInstance(). This will return a NumberFormat object that uses the standard currency representation for your default Locale (or optionally, the one you pass in).
To right justify, you can use String.padLeft().
Example:
def formatter = java.text.NumberFormat.currencyInstance
def values = [0, 100000000, 9123123.25, 10.20, 1907.23]
def formatted = values.collect { formatter.format(it) }
def maxLen = formatted*.length().max()
println formatted.collect { it.padLeft(maxLen) }.join("\n")
//output
$0.00
$100,000,000.00
$9,123,123.25
$10.20
$1,907.23
In grails soemthing like this will format it nicely with comma separators.
<g:formatNumber number="${150000}" type="currency" currencyCode="USD"/>
For right aligning I would use style:
<td style='text-align:right;...'>

Excel wrongly converts ranges into dates, how to avoid it?

I have a .tsv file with some fields being ranges like 1 - 4. I want to read these fields as they are textually written. However, upon file opening excel converts automatically those range fields to dates. For instance 1 - 4 is converted to 4-Jan. If I try to format back the cell to another type, the value is already changed and I can only get a useless number (39816). Even if the range fields are within double quotes, the wrong conversion to date still takes place. How to avoid this behavior?
I think you best use the import facility in excel but you may have to manually change the file extension to a csv.
When importing be sure to select text for all the columns with these values.
My question is in fact a duplicate of at least:
1) Stop Excel from automatically converting certain text values to dates
2) Excel: Default to TEXT rather than GENERAL when opening a .csv file
The possible solutions for Excel are to 1) either writing the fields with special double quotes like "May 16, 2011" as "=""May 16, 2011""" or 2) importing the csv/tsv file with the external data wizard and then selecting manually which columns you want to read as TEXT and not GENERAL (which could convert fields to dates)
As for my use case, I was only using Excel to remove some columns. None of the solutions was appealing to me because I wouldn't like to rewrite the tsv files with special quotes and because I had hundreds of columns and I didn't want to select each manually to be read as TEXT.
Therefore I wrote a scala script to filter tsv files by column names:
package com.jmcejuela.ml
import java.io.InputStream
import java.io.Writer
import scala.io.Codec
import scala.io.Source
import Table._
/**
* Class to represent tables with a fixed size of columns. All rows have the same columns.
*/
class Table(val rows: Seq[Row]) {
lazy val numDiffColumns = rows.foldLeft(Set[Int]())((set, row) => set + row.size)
def toTSV(out: Writer) {
if (rows.isEmpty) out.write(TableEmpty.toString)
else {
out.write(writeLineTSV(rows.head.map(_.name))) //header
rows.foreach(r => out.write(writeLineTSV(r.map(_.value))))
out.close
}
}
/**
* Get a Table with only the given columns.
*/
def filterColumnsByName(columnNames: Set[String]): Table = {
val existingNames = rows.head.map(_.name).toSet
assert(columnNames.forall(n => existingNames.contains(n)), "You want to include column names that do not exist")
new Table(rows.map { row => row.filter(col => columnNames.contains(col.name)) })
}
}
object TableEmpty extends Table(Seq.empty) {
override def toString = "Table(Empty)"
}
object Table {
def apply(rows: Row*) = new Table(rows)
type Row = Array[Column]
/**
* Column representation. Note that each column has a name and a value. Since the class Table
* is a sequence of rows which are a size-fixed array of columns, the name field is redundant
* for Table. However, this column representation could be used in the future to support
* schemata-less tables.
*/
case class Column(name: String, value: String)
private def parseLineTSV(line: String) = line.split("\t")
private def writeLineTSV(line: Seq[String]) = line.mkString("", "\t", "\n")
/**
* It is assumed that the first row gives the names to the columns
*/
def fromTSV(in: InputStream)(implicit encoding: Codec = Codec.UTF8): Table = {
val linesIt = Source.fromInputStream(in).getLines
if (linesIt.isEmpty) TableEmpty
else {
val columnNames = parseLineTSV(linesIt.next)
val padding = {
//add padding of empty columns-fields to lines that do not include last fields because they are empty
def infinite[A](x: A): Stream[A] = x #:: infinite(x)
infinite("")
}
val rows = linesIt.map { line =>
((0 until columnNames.size).zip(parseLineTSV(line) ++: padding).map { case (index, field) => Column(columnNames(index), field) }).toArray
}.toStream
new Table(rows)
}
}
}
Write 01-04 instead of 1-4 in excel..
I had a "text" formatted cell in excel being populated with a chemical casn with the value "8013-07-8" that was being reformatted into a date format. To remedy the problem, I concatenated a single quote to the beginning of the value and it rendered correctly when viewing the results. When you click on the cell, you see the prefixed single-quote, but at least I stopped seeing it as a date.
In my case, When I typed 5-14 in my D2 excel cell, is coverts to date 14 May. With a help from somebody , I was able to change the date format to the number range (5-14) using the following approach and wanted to share it with you. (I will use my case an example).
Using cell format in excel, I converted the date format in D2 (14 May) to number first ( in my case it gave me 43599).
then used the formula below ,in excel, to convert it 5-14.
=IF (EXACT (D2, 43599), "5-14", D2).

Grails - sortableColumn - Forcing numerical sorting on numerical strings

I have number stored in my database as Strings, and I would like to sort them numerically using Grails sortableColumns. Is there anyway to do this ?
Storing numbers as formatted strings prevents them from taking advantage of native numerical sorting. Have a look at the Grails formatNumber tag that can use your desired locale to display decimal separators so you can use the actual numeric data and not have to store the formatted string for display purposes.
If the domain class you want to sort has both the formatted and unformatted numeric data, you could try something like this, substituting the sort column param as necessary:
def list = {
if (params?.sort == 'formattedNumber') {
params.sort = 'rawNumber'
}
[ records : Record.list(params) ]
}
If your domain class only has the formatted string you can try parsing it to BigDecimal (or whatever the matching numeric type is) but this may not work properly if your server's locale does not match the string format's decimal separator locale.
def list = {
def records = (params?.sort == 'formattedNumber') Record.list().sort{ it.formattedNumber.toBigDecimal() : Record.list(params)
}
[ records : records ]
}

Resources