Deconstructing type in Haskell - list

I have a data type:
data Days = Mon Int | Tue Int | Wed Int | Thu Int | Fri Int
The problem is I have no idea how to deconstruct it.
For example I need a function that returns a list where the argument is not 0 e.g:
[(Mon 1), (Tue 0), (Wed 2), (Wed 0), (Thu 0)] it should return: [(Mon 1),(Wed 2)]

I think that you need to write a "deconstruction function"
numberOfDay :: Days -> Int
numberOfDay (Mon v) = v
numberOfDay (Tue v) = v
-- and so on.
days = [(Mon 1), (Tue 0), (Wed 2), (Wed 0), (Thu 0)]
filtered = filter ((/= 0) . numberOfDay) days
After all, you could come in at any time and add another constructor that has, for example no arguments. Any mechanism that generically deconstructs a type where all constructors have the same argument list would fail at this point.
Another solution would be, to structure your code slightly different:
data Days = Mon | Tue | Wed | Thu | Fri
data DayVal = DayVal Days Int

Related

Issue with sorting a vector of C++17 Filesystem::last_write_time

I'm having an issue trying to sort a vector of files by their last write time. Sorting seems to work as intended, however sometimes even though the time string shows a higher date, the time_t is lower.
Example Output:
Wed Aug 19 01:51:07 2020 || 1597819867
Wed Aug 19 05:17:20 2020 || 1597832240
Tue Aug 18 18:54:26 2020 || 1597794866
Tue Aug 18 18:43:20 2020 || 1597794200
Tue Aug 18 18:42:38 2020 || 1597794158
Wed Aug 19 22:52:44 2020 || 1597895564 <-Wrong
Thu Aug 13 18:25:32 2020 || 1597361132 <-Wrong
Wed Aug 12 22:36:51 2020 || 1597289811 <-Wrong
Mon Aug 17 21:49:45 2020 || 1597718985
My Code:
for (int i = 0; i < 200; i++) {
auto diff = GetFileWriteTime(pth) - GetFileWriteTime(dates[i]);
if (diff > 0.0) {
itPos = dates.begin();
if (i > 0) { itPos = dates.begin() + i - 1; }
dates.insert(itPos, pth);
dates.pop_back();
break;
}
}
}

How to print from two lists

I have two lists with diffrent itemsas follows:
numbers = ['1','2','3','4','5','6','7',]
days = ['mon','tue','wed','thu','fri','sat','sun',]
I want to print from both to look like this:
result = 1
mon
2
tue
3
wed
4
thu.....etc
Is there such as code that does this?
Regards
You can use zip to combine two lists.
The zip() function is probably what you want here.
You can print such output with this.
for n, m in zip(numbers, days):
print(n, m)
Output -
1 mon
2 tue
3 wed
4 thu
5 fri
6 sat
7 sun
Hope it helps.
Update - zip function combines two equal-length collections (e.g. list) together and produces a tuple object.
This can resolve your problem.
<?php
//array 1
$numbers = ['1','2','3','4','5','6','7',];
// array 2
$days = ['mon','tue','wed','thu','fri','sat','sun',];
// use for loop
for($i = 0; $i < 7; $i++) {
echo $numbers[$i].' '.$days[$i].'<br>';
}
?>
Output -
1 mon
2 tue
3 wed
4 thu
5 fri
6 sat
7 sun

ocaml unbound constructor type error from type definition

I'd like to use dates and times in my code, so I have loaded the Calendar Lib using opam. I have a simple piece of code that demonstrates the problem (example.ml):
open CalendarLib
type datefun = date -> int
let run_datefun (f : datefun) (d : date) = (f d)
let () =
let mydate = make 2016 5 23 in
printf "Day of week = %i" run_datefun days_in_month mydate
As far as I can see the Calendar days_in_month method has a type signature of date -> int.
When I try and compile this code (corebuild -pkg calendar example.byte) I get the following error:
File "example.ml", line 3, characters 15-19:
Error: Unbound type constructor date
which seems to me like the compiler is looking for a Date constructor for a date type.
What am I doing wrong?
The functions and datatypes you'd like to use are inside the Date module, so rephrasing your code we get (I've also taken the liberty of rewriting the output phrase and inserted the missing parentheses):
open CalendarLib
type datefun = Date.t -> int
let run_datefun (f : datefun) (d : Date.t) = (f d)
let () =
let mydate = Date.make 2016 5 23 in
Printf.printf "# of days in current month = %i\n" (run_datefun Date.days_in_month mydate)
A little test (by the way, you don't need corebuild for this):
$ ocamlbuild -pkg calendar example.ml example.byte
Finished, 3 targets (3 cached) in 00:00:00.
$ _build/calendar.byte
# of days in current month = 31

C++ char arrays - same input giving different outputs

I have a cpp class that implements a Netezza User-defined function (documentation here). It takes a argument that will be a string of some date format, and converts it to YYYYMMDD format. If it isn't a valid date, it will return "99991231". Whenever I run the code on some tables, I get different outputs every time for the same inputs. I assume there is some memory issue that I am not seeing.
Logically, we set the char array retval equal to the output of the date command. If it gave a null output, we set to "99991231". Then we set a temp char array to the first 9 bytes of retval (last one being the null terminator). Then we memcpy into ret->data (a char ptr of the struct we must return).
#include <stdarg.h>
#include <string.h>
#include "udxinc.h"
#include "udxhelpers.h"
using namespace nz::udx_ver2;
class Dateconvert: public Udf
{
public:
Dateconvert(UdxInit *pInit) : Udf(pInit){}
~Dateconvert(){}
static Udf* instantiate(UdxInit *pInit);
virtual ReturnValue evaluate()
{
StringReturn* ret = stringReturnInfo();
StringArg *str;
str = stringArg(0);
int lengths = str->length;
char *datas = str->data;
string tempData = datas;
string shell_arg = tempData;
shell_arg = "'" + shell_arg + "'";
string cmd="date -d " + shell_arg + " +%Y%m%d 2>/dev/null";
FILE *ls = popen(cmd.c_str(), "r");
char retval[100];
retval[0]='n';
fgets(retval, sizeof(retval), ls);
if(!isdigit(retval[0]))
{
strcpy(retval,"99991231");
}
pclose(ls);
char temp1[9];
memcpy(temp1, retval, 8);
temp1[8]='\0';
ret->size = 9;
memcpy(ret->data, temp1, 9);
NZ_UDX_RETURN_STRING(ret);
}
};
Udf* Dateconvert::instantiate(UdxInit *pInit)
{
return new Dateconvert(pInit);
}
When I run the UDF on one distinct value in Netezza, it gives me the expected output. However, when I run it over multiple columns, the output is sometimes correct, sometimes wrong, seemingly randomly. I assume this has to be an internal memory issue. Examples:
input output
1) 8/11/2014 20140811
2) 8/11/2014 20140811
Fri 10/17/14 20141017
3) 8/11/2014 99991231
Fri 10/17/14 20141017
4) 8/11/2014 20140811
Fri 10/17/14 20141017
5) 8/11/2014 20140811
Fri 10/17/14 20141017
9-Nov-12 20121109
6) 8/11/2014 20140811
Fri 10/17/14 20141017
9-Nov-12 01241109 (what?)
7) 8/11/2014 99991231
Fri 10/17/14 20141017
9-Nov-12 20121109
Anytime there is only one call of the function, it returns the correct answer. The problem arises when it is called multiple times, which I don't understand. Why would anything be carrying over? Changing the return value size to 8 from 9 at the end of the evaluate function does not solve the issue.
This is the format by which the function is called:
select a.val1, DATECONVERT(a.val1)
from
(
select '8/11/2014' as val1 from calendar
union
select 'Fri 10/17/14' as val1 from calendar
union
select '9-Nov-12' as val1 from calendar
) a
And compile command for the UDF:
nzudxcompile /export/home/nz/dateconvert.cpp -o dateconvert.o --sig "Dateconvert(VARCHAR(200))" --version 2 --return "VARCHAR(200)" --class Dateconvert --user user1 --pw mypw --db mydb
To cut to the chase, the problem here is in how you assign tempData.
StringReturn* ret = stringReturnInfo();
StringArg *str;
str = stringArg(0);
int lengths = str->length;
char *datas = str->data;
string tempData = datas;
StringArg does not store a NUL-terminated string, but instead provides the length and expects you to manage that yourself.
select a.val1, ADMIN.DATECONVERT(a.val1)
from
(
select '09-Nov-12'::varchar(20) as val1
union all
select '9-Nov-12'::varchar(20) as val1
) a;
VAL1 | DATECONVERT
-----------+-------------
09-Nov-12 | 20121109
9-Nov-12 | 01221109
(2 rows)
In this example, what is happening is that the longer first string still has a character hanging around in memory when the second, shorter string is assigned to tempData. That hanging '2' at the end gets added on like so:
09-Nov-12
9-Nov-122
Each of these are both valid inputs to date, which nicely explains the output you are seeing.
$ date -d 09-Nov-12 +%Y%m%d
20121109
$ date -d 09-Nov-122 +%Y%m%d
01221109
Change the assignment to use that length, and you'll avoid the problem.
//string tempData = datas;
string tempData(datas, datas+lengths);
And then you get the expected output:
select a.val1, ADMIN.DATECONVERT(a.val1)
from
(
select '09-Nov-12'::varchar(20) as val1
union all
select '9-Nov-12'::varchar(20) as val1
) a;
VAL1 | DATECONVERT
-----------+-------------
09-Nov-12 | 20121109
9-Nov-12 | 20121109
(2 rows)
All that being said, I don't know that the overall approach you are taking in this UDF will work. As I'm running it above, the rows are generated on the host, because they are hard-coded in the SQL, and date is certainly available on the host. However, you can't expect the code that runs on the MPP backend (which we often refer to as SPUs) to have the same availability of linux utilities that you will find on the host, or if they exist that they have the same capabilities.
If I move the date into an actual table, the UDF will operate on it on the SPU, and it will give me bad output because the date command on the SPU image is significantly different than that of the host, and doesn't understand this input format at all.
select a.col1, admin.DATECONVERT(a.col1) from calendar a;
COL1 | DATECONVERT
-----------+-------------
09-Nov-12 | 99991231
9-Nov-12 | 99991231
(2 rows)

Basic pyephem code

I have a very simple code to get the longitude of the sun but when I compare the output to Astrolog and Astrodienst its incorrect, there is a 13 minute difference. I have not added Observer as I think default is midnight GMT (which is what I want). What am I doing wrong?
import ephem
start = ephem.date('2015/01/01')
end = ephem.date('2015/12/31')
f2 = open("Sun", 'w')
while start <= end:
sun = ephem.Sun(start)
ecl = ephem.Ecliptic(sun)
f2.write(str(ephem.date(start))+' '+ str(ecl.lon) +'\n')
start+=1
f2.close()
Example of results for 2015/12/30:
code - 2015/12/30 00:00:00 277:43:36.6
Astrodienst - 7°56'39 Cap
Thanks
The reason why the 13 minute difference is because of the epoch setting, when I added
sun = ephem.Sun(start, epoch = start)
the results were the same as swiss ephemeris.