How to save decimal heights in MongoDB - node.js

I'm facing this strange problem while saving numeric values in mongodb.
I'm saving height of people in mongodb as Number, so a person with height of 5'.1" is saved as 5.1 and a person with a height of 5'.10" is also saved as 5.1.
I can't change it to string because I have a my search query based on number, ("height" : {"$gte": req.body.height.minimum_height, "$lte": req.body.height.maximum_height}).
I'm sure there must be a way to save specific values to deal with monetary transactions, but I'm not sure how to do it in my scenario.
Any suggestions are welcome !!

Since the height is already a number, it would be better to treat it in metric units and follow the convention that it represents height in centimetres.
When retrieving heights then as #J.F. suggested in the comment it can be formatted in the client app or wherever else it is required.
When storing heights it can be converted to centimetres.
For example 5'10'' becomes (5 x 12 + 10) x 2.54 = 177.8

One solution is to use two fields: the numeric value and the display value.
For 5' 10", the numeric value is 5 + 10/12 which is 5.83333...
irb(main):001:0> 5+(10/12.0)
=> 5.833333333333333
Then use the numeric field for searches and calculations and keep 5' 10" in the display field for rendering to users.
Alternatively you can only store the numeric value and calculate the display value:
irb(main):007:0> i = (5.833333333333333 * 12).round; f = i / 12; i = i % 12
=> 10
irb(main):008:0> f
=> 5
irb(main):009:0> i
=> 10
irb(main):010:0> "#{f}' #{i}\""
=> "5' 10\""
irb(main):011:0>

Related

Why I get error message "Invalid number" since UserID is NUMBER

I am little bit confusing and have no idea where I made mistake.
SELECT uta.StartDate, uta.EndDate FROM user_timesheets_absence uta
WHERE uta.UserID = 353
AND uta.Approved = 'true'
AND '2020-03-06' BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD') AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY
In following query I get error
ORA-01722: invalid number
I try to understand where the error is, but when I realize query a deeper I can not see where the error is.
ABSENCETYPE VARCHAR2(255 CHAR)
ANSWER VARCHAR2(500 CHAR)
APPROVED NUMBER(10,0)
COMMENT_ CLOB
DAYS NUMBER(10,0)
ENDDATE VARCHAR2(50 CHAR)
ISANSWERED NUMBER(10,0)
ISREJECTED NUMBER(10,0)
STARTDATE VARCHAR2(50 CHAR)
USERABSENCEID NUMBER(10,0)
USERHASSEEN VARCHAR2(500 CHAR)
USERID NUMBER(10,0)
WIDTH NUMBER(10,0)
When I insert data into table, I use this kind of data and It works fine. But when I use SELECT statment I get error. I hope the error was UserID but it wasn't.
Insert into DB.USER_TIMESHEETS_ABSENCE (ABSENCETYPE,ANSWER,APPROVED,DAYS,ENDDATE,ISANSWERED,ISREJECTED,STARTDATE,USERABSENCEID,USERHASSEEN,USERID,WIDTH) values ('1','ne',0,8,'2020-02-06',1,1,'2020-01-30',89,'1',348,160);
Can someone tell me, where I made mistake ? What is wrong here ?
There is more than one problem in this query.
Firstly, here:
AND uta.Approved = 'true'
approved is a number, but you are comparing it against string 'true'. This does not work. Use a literal number on the right side of the equal sign.
Then, here:
AND '2020-03-06'
BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY
You are comparing a string against dates. This won't work. You probably want a literal date on the left side of between. I would also recommend using + 1 rather than the interval syntax, which should be reserved to timestamps:
AND DATE '2020-03-06'
BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + 1
Why are STARTDATE and ENDDATE defined as strings rather than date. Not using the correct data types is a surefire way to introduce data corruption issues. That's certainly where I would start looking.
The other thing is, always use explicit casting when converting strings into dates (or numbers) and vice versa. In this case you should use a date literal. Instead of
AND '2020-03-06' BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD') AND TO_DATE(uta.EndDate,'YYYY-MM-DD')
use
AND date '2020-03-06' BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD') AND TO_DATE(uta.EndDate,'YYYY-MM-DD')
If you have got data corruption in your date columns and you're on 12c or later you can use VALIDATE_CONVERSATION to filter rows which don't contain valid dates:
SELECT uta.StartDate, uta.EndDate FROM user_timesheets_absence uta
WHERE uta.UserID = 353
AND uta.Approved = 'true'
AND validate_conversion(uta.StartDate,'YYYY-MM-DD') = 1
AND validate_conversion(uta.EndDate,'YYYY-MM-DD') = 1
AND date '2020-03-06' BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD') AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY
You can also use this to find invalid date strings:
SELECT *
FROM user_timesheets_absence uta
WHERE validate_conversion(uta.StartDate,'YYYY-MM-DD') = 0
OR validate_conversion(uta.EndDate,'YYYY-MM-DD') = 0

Can nested LookUp be done?

Hi again dear stackoverflowers!
I have one column in Sharepoint for an ID number (say that the number is 29) and another column that for that ID holds different subIDs (29.1, 29.2, 29.3, etc.).
What I need is that my PowerApp looks up into the Sharepoint list and takes the maximum subID number associated with the ID given, and automatically sums 0.1, because I do not want people to introduce two equal subIDs.
I'll give you the formula I tried (but the problem is that StartsWith is for text and Max is for numbers), so if you have any ideas about how can it be solved or you have any function that works with both text and numbers I would really appreciate it:
LookUp(my_list.'Prueba', StartsWith('Prueba' , DataCardValue9_2.Text), Max('Prueba')+0.1)
Another thing I tried was to nest LookUp functions, but that did not work either, do you know if that can be done?
LookUp(my_list, Prueba = DataCardValue9_2.Text + 0.3 , Max(Prueba) + 0.1) & LookUp(my_list, Prueba = DataCardValue9_2.Text + 0.2 , Max(Prueba) + 0.1) & LookUp(my_list, Prueba = DataCardValue9_2.Text + 0.1 , Max(Prueba) + 0.1)
Thank you very much for your time and help.
You must convert your column to a number datatype. Value() function for number.
Please do check this link: https://learn.microsoft.com/en-us/powerapps/maker/canvas-apps/functions/function-value

NPOI: Achieve Currency format as if formatted by Excel

I have seen some questions (like this one) here asking about if a cell in Excel can be formatted by NPOI/POI as if formatted by Excel. As most of you, I have to deal with issues with Currency and DateTime. Here let me ask how the formatting can be achieved as if it has been formatted by Excel? (I will answer this question myself as to demonstrate how to do it.)
Setting: Windows 10, English, Region: Taiwan
Excel format: XLSX (version 2007 and later)
(Sorry about various edit of this question as I have pressed the 'Enter' button at unexpected time.)
If you format a cell as Currency, you have 4 choices:
The internal format of each style is as follow:
-NT$1,234.10
<numFmt formatCode=""NT$"#,##0.00" numFmtId="164"/>
[RED]NT$1,234.10
<numFmt formatCode=""NT$"#,##0.00;[Red]"NT$"#,##0.00" numFmtId="164"/>
-NT$1,234.10
<numFmt formatCode=""NT$"#,##0.00_);("NT$"#,##0.00)" numFmtId="7"/>
[RED]-NT$1,234.10
<numFmt formatCode=""NT$"#,##0.00_);[Red]("NT$"#,##0.00)" numFmtId="8"/>
Note: There is a pair of double quote (") comes before and after NT$.
(To get internal format of XLSX, just unzip it. The Style information is available in <unzip dir>\xl\Styles.xml Check out this answer if you need more information.)
(FYI: In formatCode, the '0' represent a digit. The '#' also represent a digit, but will not appear if the number is not large enough. So any number less than 1000 will not have the comma inside it. The '_' is a space holder. In format 3, '1.75' appears as 'NT$1.75 '. The last one is a space.)
(FYI: In numFmtId, for case 1 and case 2, number 164 is for user-defined. For case 3 and 4, number 7 and 8 are build-in style.)
For developers using POI/NPOI, you may find out if you format your currency column using Build In Format using 0x7 or 0x8, you can get only the third or fourth choice. You cannot get the first or second choice.
To get the first choice, you build upon style 0x7 "$#,##0.00);($#,##0.00)". You need to add the currency symbol and the pair of double quotes in front of it.
styleCurrency.DataFormat = workbook.CreateDataFormat().GetFormat("\"NT$\"#,##0.00");
Apply this format to a cell with number. Once you open the Excel result file, right click to check formatting, you will see the first choice.
Please feel free to comment on this post.
var cell5 = row.CreateCell(5, CellType.Numeric);
cell5.SetCellValue(item.OrderTotal);
var styleCurrency = workbook.CreateCellStyle();
styleCurrency.DataFormat= workbook.CreateDataFormat().GetFormat(string.Format("\"{0}\"#,##0.00", item.CurrencySymbol));//styleCurrency;
cell5.CellStyle = styleCurrency;
styleCurrency = null;
Iterate over loop for multiple currency.
Function to GetCurrencySymbol against currency Code on C#
private string GetCurencySymbol(string isOcurrencyCode)
{
return CultureInfo.GetCultures(CultureTypes.AllCultures).Where(c => !c.IsNeutralCulture)
.Select(culture =>
{
try
{
return new RegionInfo(culture.LCID);
}
catch
{
return null;
}
})
.Where(ri => ri != null && ri.ISOCurrencySymbol == isOcurrencyCode)
.Select(ri => ri.CurrencySymbol).FirstOrDefault();}

How to remove percent character from a string in Cognos?

I have a string field with mostly numeric values like 13.4, but some have 13.4%. I am trying to use the following expression to remove the % symbols and retain just the numeric values to convert the field to integer.
Here is what I have so far in the expression definition of Cognos 8 Report Studio:
IF(POSITION('%' IN [FIELD1]) = NULL) THEN
/*** this captures rows with valid data **/
([FIELD1])
ELSE
/** trying to remove the % sign from rows with data like this 13.4% **/
(SUBSTRING([FIELD1]), 1, POSITION('%' IN [FIELD1])))
Any hints/help is much appreciated.
An easy way to do this is to use the trim() function. The following will remove any trailing % characters:
TRIM(trailing '%',[FIELD1])
The approach you are using is feasable. However, the syntax you are using is not compatible with the version of the ReportStudio that I'm familiar with. Below you will find an updated expression which works for me.
IF ( POSITION( '%'; [FIELD1]) = 0) THEN
( [FIELD1] )
ELSE
( SUBSTRING( [FIELD1]; 1; POSITION( '%'; [FIELD1]) - 1 ) )
Since character positions in strings are 1-based in Cognos it's important to substract 1 from the position returned by POSITION(). Otherwise you would only cut off characters after the percent sign.
Another note: what you are doing here is data cleansing. It's usually more advantageous to push these chores down to a lower level of the data retrieval chain, e.g. the Data Warehouse or at least the Framework Manager model, so that at the reporting level you can use this field as numeric field directly.

String Concatenation

As I asked in my previous question(Link) about concatenating a multipart string of variable lengths, I used the method answered there by rkhayrov and now, my function looks like this:
local sToReturn = string.format( "\t%03s\t%-25s\t%-7s\n\t", "S. No.", "UserName", "Score" )
SQLQuery = assert( Conn:execute( string.format( [[SELECT username, totalcount FROM chatstat ORDER BY totalcount DESC LIMIT %d]], iLimit ) ) )
DataArray = SQLQuery:fetch ({}, "a")
i = 1
while DataArray do
sTemp = string.format( "%03s\t%025s\t%-7d", tostring(i), DataArray.username, DataArray.totalcount )
sToReturn = sToReturn..sTemp.."\n\t"
DataArray = SQLQuery:fetch ({}, "a")
i = i + 1
end
But, even now, the value of score is still not following the order as required. The max length of username is 25. I've used %025s inside the while loop because I want the usernames to be right-justified, while the %-25s is to make the word UserName centre justified.
EDIT
Current output:
Required Output:
Displaying the list of top 5 chit-chatters.
S. No. UserName Score
1 Keeda 9440
2 _2.2_™ 7675
3 aim 7057
4 KGBRULES 6770
5 Guddu 6322
I think it's because of difference in fonts, but since most of the clients have Windows 7 default fonts(Tahoma/Verdana at 11px), I need optimum result for at-least that.
I think it's because of difference in fonts
It is. string.format formats by inserting whitespace. That only works for a fixed width fonts (i.e. all characters have the same width, including whitespace).
since most of the clients have Windows 7 default fonts(Tahoma/Verdana at 11px)
In what? How are they viewing your output? Do you write it to a textfile, that they then open in the editor of their choice (likely Notepad)? Then this approach will simply not work.
Don't know enough about your output requirements to steer you any futher, but it's worth noting that everyone has a browser so HTML output is very portable.
string.format doesn't truncate - the width of the field is minimum, not maximum. You'll have to truncate the strings to 25 characters yourself with something like DataArray.username:sub(0,25).
I'd remove the tabs from the string.format; and use the justification provided by %25s only. Won't be perfect but will probably be closer.
Use a fixed-width font if you can.

Resources