constraints inlist for integer - grails

I need to write a constraint for credit card expiry year in the constraints
This is my constraints
static constraints = {
cardNumber(nullable:false, blank:false, creditCard:true)
expiryMonth(nullable:false, range:1..12)
expiryYear(nullable:false, range:(defaultExpiryYear)..(defaultExpiryYear + YEARS_TO_LIST))
}
where defaultExpiryYear = Current Year - 2000
and YEARS_TO_LIST = 10 years.
But this case will fail if the year is 2095 because the range will go expiryYear(nullable:false, range:95..105)
but as the expiryYear is only 2 digit for the year 2105 it will give 05 and it will fail.
How do I convert it into get in inlist for the range?

I could be wrong but from my point of view, you should not worry about things that are about 90 years in the future. in 90 years - who could guarantee that there are still credit cards? if there are still credit cards, will they have an "expiry year"? if they'll have an expiry date, how is it calculated?
so, sorry that this may not be the answer you expected, but given the speed of development of the past few years I would not worry about your problem in any way ;)

This is how i fix it please comment if you have any other good ideas
where epiryStartYear and expiryEndYear are 4 digits year
expiryYear(nullable:false, InList:( getExpiryRangeList()))
def static private getExpiryRangeList() {
def yearList = []
(expiryStartYear..expiryEndYear).each {
yearList << it % 100
}
yearList
}
OR i can do
def static private getExpiryRangeList() {
[expiryStartYear..expiryEndYear].collect(it % 100)
}

Related

Calculating Age in X++

I am trying to calculate an age in x++ where the customer is born on 1/6/2010 to the selected day of his visit - 1/6/2023 today but the result doesn't give me 13 years old but gives me 12.
real ageDiffReal;
int ageDiffInt;
date datetoday = DateTimeUtil::date(Visitas.RFC_DataVisita);
ageDiffReal = (datetoday - mkDate(dir.BirthDay,dir.BirthMonth,dir.BirthYear)) / 365.242199;
ageDiffInt = Round(ageDiffReal,0);
info(strFmt('%1,%2',ageDiffReal, ageDiffInt));
I tried with / 365 and with 365.25 because of leap years but still didn't work well
You're using round(...) incorrectly.
ageDiffInt = decRound(ageDiffReal, 0); // Better
ageDiffInt = round(ageDiffReal, 1); // Works too
round(...) - The number that is a multiple of the value specified by the _decimals parameter and is closest to the value specified by the _arg parameter.
See https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-ref/xpp-math-run-time-functions

How to do I manipulate my code for a maximum of one buy order and one sell order and the same time

#property strict
int ticket;
void OnTick()
{
double AccountBal;
double MAfast = iMA(_Symbol,PERIOD_CURRENT,20,0,MODE_EMA,PRICE_CLOSE,0);
double MAslow = iMA(_Symbol,PERIOD_CURRENT,30,0,MODE_EMA,PRICE_CLOSE,0);
AccountBal = AccountBalance()/10000;
double Force = iForce(_Symbol,PERIOD_CURRENT,13,MODE_SMA,PRICE_CLOSE,0);
double rsi = iRSI(_Symbol,PERIOD_CURRENT,7,PRICE_CLOSE,0);
if((rsi> 70)&&(OrdersTotal()==0)&&(MAfast>MAslow)){
ticket = OrderSend(_Symbol,OP_BUY,AccountBal,Ask,10,Ask-0.007,Ask+0.007,"This iS Buy",33,0,clrBlue);
}
if((rsi <30)&&(OrdersTotal()==0)&&(MAslow>MAfast)){
ticket = OrderSend(_Symbol,OP_SELL,AccountBal,Bid,10,Bid+0.007,Bid-0.007,"This is a Sell",33,0,clrRed);
}
}
The code works and everything is great but when a order is open like a buy order, even if the the conditions are true for sell order it wont place the order until the open one hits take profit or stop loss, the Orders Total function is screwing me over is there anyway I can replace it?

Memory/CPU optimzation?

My program uses alot of memory and Processing power, I can only search up to 6000, is there any way to reduce the amount of memory this uses? This will really help with future programming endevours as it will be nice to know how to work with memory smartly.
ArrayList<Integer> factor = new ArrayList<Integer>();
ArrayList<Integer> non = new ArrayList<Integer>();
ArrayList<Integer> prime = new ArrayList<Integer>();
Scanner sc = new Scanner(System.in);
System.out.println("Please enter how high we want to search");
long startTime = System.nanoTime();
int max = sc.nextInt();
int number = 2;
while (number < max)
{
for (int i=0;i<prime.size();i++)
{
int value = prime.get(i);
if (number % value == 0)
{
factor.add(value);
}
else
{
non.add(value);
}
}
if(factor.isEmpty())
{
prime.add(number);
}
else
{
composite.add(number);
}
factor.clear();
number++;
}
int howMany=prime.size();
System.out.printf("The are "+howMany+" prime numbers up to " +max + " and they are: " +prime );
System.out.println();
}
You do not say what language you are using, so this answer will be general.
To store primes up to 6,000 you only need about 3,000 bits which is less than 380 bytes. Your basic solution is the Sieve of Eratosthenes and the fact that 2 is the only even prime. You set up the sieve to handle only odd numbers, which halves the storage needed. Since the sieve only holds prime or not prime for each odd number, the storage can be reduced to a single bit for each number.
Once you have set up your sieve, there are many sites including this one which have instructions in different languages, you just need to retrieve the prime/not prime value from the sieve for the numbers in your range. Here is the pseudocode for checking if a number is prime, assuming the sieve has already been set up:
boolean function isPrime(number)
// Low numbers
if (number < 2)
return false
endif
// Even numbers
if (number is even)
return number == 2
endif
// Odd numbers >= 3
return sieve[(number - 1) / 2] == 1
end function
Low numbers are not prime. 2 is the only even prime; all other even numbers are not prime. The prime flag for the odd number 2n+1 is stored at bit n in the sieve. This assumes that the language you are using allows bit level access, something like a BitSet in Java.

Lua seconds format questions

I have this function:
function SecondsFormat(X)
if X <= 0 then return "" end
local t ={}
local ndays = string.format("%02.f",math.floor(X / 86400))
if tonumber(ndays) > 0 then table.insert(t,ndays.."d ") end
local nHours = string.format("%02.f",math.floor((X/3600) -(ndays*24)))
if tonumber(nHours) > 0 then table.insert(t,nHours.."h ") end
local nMins = string.format("%02.f",math.floor((X/60) - (ndays * 1440) - (nHours*60)))
if tonumber(nMins) > 0 then table.insert(t,nMins.."m ") end
local nSecs = string.format("%02.f", math.fmod(X, 60));
if tonumber(nSecs) > 0 then table.insert(t,nSecs.."s") end
return table.concat(t)
end
I would like to add weeks and months to it but cant get my head around the month part to move on to the week part just because the days in a month aren't always the same so can anyone offer some help?
The second question is, is using a table to store the results the most efficient way of dealing with this given the function will be called every 3 seconds for up to 100 items (in a grid)?
Edit:
function ADownload.ETA(Size,Done,Tranrate) --all in bytes
if Size == nil then return "--" end
if Done == nil then return "--" end
if Tranrate == nil then return "--" end
local RemS = (Size - Done) / Tranrate
local RemS = tonumber(RemS)
if RemS <= 0 or RemS == nil or RemS > 63072000 then return "--" end
local date = os.date("%c",RemS)
if date == nil then return "--" end
local month, day, year, hour, minute, second = date:match("(%d+)/(%d+)/(%d+) (%d+): (%d+):(%d+)")
month = month - 1
day = day - 1
year = year - 70
if tonumber(year) > 0 then
return string.format("%dy %dm %dd %dh %dm %ds", year, month, day, hour, minute, second)
elseif tonumber(month) > 0 then
return string.format("%dm %dd %dh %dm %ds",month, day, hour, minute, second)
elseif tonumber(day) > 0 then
return string.format("%dd %dh %dm %ds",day, hour, minute, second)
elseif tonumber(hour) > 0 then
return string.format("%dh %dm %ds",hour, minute, second)
elseif tonumber(minute) > 0 then
return string.format("%dm %ds",minute, second)
else
return string.format("%ds",second)
end
end
I merged the function into the main function as I figured it would probably be quicker but I now have two questions:
1: I had to add
if date == nil then return "--" end
because it errors occasionally with date:match trying to compare with "nil" however os.date mentions nothing in the literature about returning nil as its a string or a table so although the extra line of code fixes the issue I'm wondering why that behaviour occurs as I'm sure I caught all the non events in the previous returns?
2: Sometimes I see functions written like myfunction(...) and I'm sure that just does away with the arguments and if so is there a one line of code that could do away with the first 3 "if" statements?
You can use the os.date function to get date values in a useable format. The '*t' formating parameter makes the returned date into a table instead of a string.
local t = os.date('*t')
print(t.year, t.month, t.day, t.hour, t.min, t.sec)
print(t.wday, t.yday)
os.data uses the current time by default, you can pass it an explicit time if you want (see the os.data docs for more info on this)
local t = os.date('*t', x)
As for table performance, I wouldn't worry about that. Not only is your function not called all that often, but table handling is much cheaper than other things you might be doing (calling os.date, lots of string formatting, etc)
Why not let Lua's os library do the hard work for you?
There is probably an easier (read: better) way to figure out the difference to 01/01/70, but here is a quick idea of how you could use it:
function SecondsFormat(X)
if X <= 0 then return "" end
local date = os.date("%c", X) -- will give something like "01/03/70 03:40:00"
local inPattern = "(%d+)/(%d+)/(%d+) (%d+):(%d+):(%d+)"
local outPattern = "%dy %dm %dd %dh %dm %ds"
local month, day, year, hour, minute, second = date:match(inPattern)
month = month - 1
day = day - 1
year = year - 70
return string.format(outPattern, year, month, day, hour, minute, second)
end
I think that this should also be a lot quicker than constructing the table and calling string.format multiple times - but you'd have to profile that.
EDIT: I ran a quick test with two functions that concatenate "abc", "def" and "ghi" using both methods. Inserting those strings into a table an concatenating took 14 seconds (for several million runs of course) and using a single string.format() took 6 seconds. This does not take into account, that your code calls string.format() anyway (multiple times) - nor the difference between you figuring out the values by division and I by pattern matching. Pattern matching is certainly slower, but I doubt that it outweighs the gains from not having a table - and it's certainly convenient to be able to leverage os.time(). The fastest way would probably be figuring out the month and day manually and then using a single string.format(). But again - you'd have to profile that.
EDIT2: missingno has a good point with using the "*t" option with os.date to give you the values separately in the first place. Again, this depends on whether you want to have a table for convenience vs. a string for storage or whatever reasons. Combining "*t" and a single string.format:
function SecondsFormat(X)
if X <= 0 then return "" end
local date = os.date("*t", X) -- will give you a table
local outPattern = "%dy %dm %dd %dh %dm %ds"
date.month = date.month - 1
date.day = date.day - 1
date.year = date.year - 70
return string.format(outPattern, date.year, date.month, date.day, date.hour, date.min, date.sec)
end

Extended EDT does not compare dates

There are two EDTs which extend from Transdate. And they both have same values.
The purpose is to compare two dates and then execute the remaining loop. But it is not executing the loop.
The problem is not about comparison. Example:
x = 5/1/2012; // showing error if we give like this
y = 5\1\2012;
z = systemdateget(); //but taking the same value as x
if(x == z)
{
.........
}
if(y == z)
{
..............
}
I tested the above job and it is just for example and understanding, but my main problem is about date compatibility.
Your date constant should be written as 1\5\2012 in day, month, year order.
Remember: AX is made in Denmark.

Resources