How can a decimal number with a comma be converted in a decimal (Point) in SwiftUI? - formatting

How can a textField were a comma is inserted be Formated so the inserted Decimal value example 10,05$ can be converted to a decimal(Point) 10.05$?
private static let Intrest = "Intrest"
private static let Repayment = "Repayment"
var loan: Double {
let intrest = Double (Intrest)
let repayment = Double (Repayment)
let Loan = Intrest + Repayment
return Loan
}
var body: some View {
VStack{
HStack{
Text ("Repayment %")
Spacer()
TextField("2 %", text: $Repayment)
.keyboardType(.decimalPad)
}
VStack{
HStack{
Text ("Loan / month")
}
TextField("2 %", text: $Loan)
.keyboardType(.decimalPad)
}
}
The problem only occurs because in many countries mostly comma is used which breaks the calculation.
Thanks

You need to make sure you convert your string into a double with point and not comma.
This one should help.
Swift playground - How to convert a string with comma to a string with decimal

I suggest you read Textfield not updating and use custom string binding with double back storage.
Specifically read the Update there :-)
Complete example usage of custom string binding with backend double number is here https://gist.github.com/op183/24607b6309f7d1ea8f3aaf02d17e4ed3

Related

Print values from HashMap

Currently, I am trying to write a method to locate the highest value product in my hashmap.
I am looking for a push in the right direction if that is possible. I appreciate any help that might be pointed my way. Thank you.
In order to be consistent, I would suggest you using horizontal tab \t as the divider.
To align the text in the right columns, I would also create a method which adds some whitespaces right after the product name (e.g jeans). The number of input whitespaces should be equal to the subtraction of the column title (e.g Description) and the product name (e.g jeans).
Try this code:
fun addWhitespaces(input: String, referencedWord: String = "Description"): String
{
var ws = ""
(0..(referencedWord.length - input.length)).map { ws += " " }
return ws
}
The method addWhitespaces() is called within the last print.
products.maxBy { it.value.second } ?.let { (key, value) ->
println("The highest priced product is: ")
println()
println("Item#\tDescription\tPrice")
println("-----\t-----------\t-----")
println("$key \t${value.first}${addWhitespaces(value.first)}\t${value.second}")
}
Also as Ali Gelenler mentioned, you should check for the null condition as the result of maxBy() may be null.
maxBy returns nullable Map.Entry so you need to handle nullable result. You could for example use safe call with ? following by let as below.
products.maxBy { it.value.second }?.let {
val (key, value) = it
println("The highest priced product is: ")
println()
println("Item# Description Price")
println("----- ------------- -------")
println("$key ${value.first} ${value.second}")
}
Your print statement is the default format from the map entry. Change your print statement to something like this:
println("${highestPricedProduct.key}\t${highestPricedProduct.value.first}\t${highestPricedProduct.value.second}")

How to print double value in DecimalFormat

I have a code.
Double value = 6.589715E7;
DecimalFormatSymbols symbol = new DecimalFormatSymbols(Locale.GERMANY);
symbol.setGroupingSeparator(',');
final DecimalFormat doris = new DecimalFormat("#,###000",symbol );
System.out.println(changedValue);
which displays the value like this rite now.
65,897150
is there any way out this can be displayed as.
65,9 (also rounding off to one decimal place)
This example rounds up 2 but you get the point, try this
inputValue = Math.Round(inputValue, 2);
Here I put answer in string format. you can also convert into double format.
Double value = 6.589715E7;
DecimalFormatSymbols symbol = new DecimalFormatSymbols(Locale.GERMANY);
symbol.setGroupingSeparator(',');
final DecimalFormat doris = new DecimalFormat("##,###000",symbol );
String str = String.valueOf(doris.format(value));
String formated=str.replace(".", ",").substring(0,str.indexOf(",")+2);
Log.e("Log","d result="+formated);

xpages currency incomplete entry failing

I have a form that accepts currency from several fields and depending on what I enter into one, it calculates others. For this most part the code below works (example being the invoice amount field)
<xp:inputText value="#{FInvoiceDoc.InvoiceAmount}" id="InvoiceAmount">
<xp:this.converter>
<xp:convertNumber type="currency"></xp:convertNumber></xp:this.converter>
<xp:eventHandler event="onchange" submit="false" id="eventHandler5">
<xp:this.script><![CDATA[var rate = XSP.getElementById("#{id:ExchangeRate}").value;
var stAmount = XSP.getElementById("#{id:InvoiceAmount}").value;
var stTvat = XSP.getElementById("#{id:TVAT}").value;
var stTst = XSP.getElementById("#{id:TST}").value;
var stToop = XSP.getElementById("#{id:Toop}").value;
var tmp;
// get the dojo currency code
dojo.require("dojo.currency");
// get the numeric values using parse
amount = dojo.currency.parse(stAmount,{currency:"USD"});
total = rate * amount;
XSP.getElementById("#{id:EstUSAmount}").innerHTML = dojo.currency.format(total,{currency:"USD"});
XSP.getElementById("#{id:InvoiceAmount}").value = dojo.currency.format(amount,{currency:"USD"});
if (amount != 0) {
tvat = dojo.currency.parse(stTvat,{currency:"USD"});
tst = dojo.currency.parse(stTst,{currency:"USD"});
toop = dojo.currency.parse(stToop,{currency:"USD"});
tmp = (tvat / (amount-tvat-tst-toop)) * 100;
XSP.getElementById("#{id:VP}").innerHTML = tmp.toFixed(2);
tmp = (tst / (amount-tvat-tst-toop)) * 100;
XSP.getElementById("#{id:STP}").innerHTML = tmp.toFixed(2);
tmp = (toop / (amount-tvat-tst-toop)) * 100;
XSP.getElementById("#{id:OoPP}").innerHTML = tmp.toFixed(2);
}
]]></xp:this.script>
</xp:eventHandler>
</xp:inputText>
Like I said, for the most part this works, but if I enter only a partial number like
200.2
instead of
200.20
then it fails. Most data entry folks will want to not have to key in the last "0" just so it's legal.
btw, if I enter it in as just 200 with no cents, it's OK.
It's as if the statement;
amount = dojo.currency.parse(stAmount,{currency:"USD"});
requires a 2 digit penny amount or no pennys, but doesn't like just the leading cents digit.
Any way around this?
The currency format is very restrictive and needs the certain number of decimal places for a given currency. As you can see here there can be different number of decimal places depending on currency. For most currencies it needs two decimal places though. But, you can trick the parser. Just try it with standard number of decimal places and if it fails try it with one decimal place again. Your code would look like this then:
var amount = dojo.currency.parse(stAmount,{currency:"USD"});
if (!amount && amount!==0) {
amount = dojo.currency.parse(stAmount,{currency:"USD",places:"1"});
}
This accepts inputs like
12
12.3
12.34
$12
$12.3
$12.34
But it is still very picky. It doesn't accept spaces or more decimal places then currency allows.
If you want more flexibility for your users and need USD currency only I'd go for dojo.number or other number parsing instead and show the "$" outside the input field. Then, you'd be able to accept much more formats and could add functions like rounding.
Yeah, I've played with the converters. Thing is I want the converter to stay "Currency". The data I receive from the notes database is always correct and formats properly. Its the manipulation that I''m having a problem with. Since this is all on the client side, I've created a function that I can reuse throughout the page.
<script>
function isNumeric(n) {
n = parseFloat(n);
return !isNaN(n) || n != n;
}
// We call this if its a currency amount. If they only entered one number after
// the decimal, then we just append a 0. We're expecting a string and we send
// the string back.
function cMask(Amount)
{
if (Amount == "") { return "0.00" }
a = Amount.split(".");
if (a.length == 2)
{
if (a[1] != null)
{
if (a[1].length == 1)
{
Amount = Amount + "0";
}
}
}
// get the dojo currency code
dojo.require("dojo.currency");
b = dojo.currency.parse(Amount,{currency:"USD"});
if (isNumeric(b)) {return Amount} else {return "0.00"}
}
</script>
Then its a matter of just changing the initial variable load line.
var stAmount = cMask(XSP.getElementById("#{id:InvoiceAmount}").value);
Seems to work and I've just taught myself how to create reusable client-side javascript for my page.

VB 2010: How to index textbox (making it like slots)?

If the title isn't clear; I want to be able to select any character from textbox without making some complex loops-dependent code (I can do that one). For example, let's consider this text is entered in a textbox:
hello user!
I want some syntax when I tell to get me the index 1's value, it gives me "h", for index 5 = "o"... etc
So, anyone knows what's the right syntax, please help!
string can be directly indexed without any special code.
//from metadata
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
{
....
// Summary:
// Gets the character at a specified character position in the current System.String
// object.
//
// Parameters:
// index:
// A character position in the current string.
//
// Returns:
// A Unicode character.
//
// Exceptions:
// System.IndexOutOfRangeException:
// index is greater than or equal to the length of this object or less than
// zero.
public char this[int index] { get; }
....
}
dim str = "hello";
dim hchar = str(0);
dim echar = str(1);
dim lchar = str(2);
ect
Dim x As String = "Hello"
Console.Write(x.IndexOf("e")) 'Would return the position
Console.Write(x(x.IndexOf("e"))) 'Would return the character based upon the position
Console.Write(x(1)) 'Returns the character based at position 1 of the string
You can remove the Console.Write if you are using a WinForm.
TextBox1.Text = x(x.IndexOf("e"))
This should work.
Dim orig = "hello user!"
Dim res = Enumerable.Range(0,orig.Length).[Select](Function(i) orig.Substring(i,1))
So then you can do:
Dim x = res(0) 'x = "h"

optimize a string.Format + replace

I have this function. The visual studio profile marked the line with string.Format as hot and were i spend much of my time.
How can i write this loop more efficiently?
public string EscapeNoPredicate(string sz)
{
var s = new StringBuilder(sz);
s.Replace(sepStr, sepStr + sepStr);
foreach (char v in IllegalChars)
{
string s2 = string.Format("{0}{1:X2}", seperator, (Int16)v);
s.Replace(v.ToString(), s2);
}
return s.ToString();
}
Instead of calculating s2s foreach v each time this method is called; you can store them precalculated. Of course I am assuming IllegalChars and seperator remains same.
In a string.format you can put objects, so (Int16)v is not needed. You can supply "v"