Post Reply 
epoch Prime
01-06-2018, 09:40 AM (This post was last modified: 01-06-2018 12:06 PM by StephenG1CMZ.)
Post: #21
RE: epoch Prime
Re Optional Parameters
The HP Prime does not have optional parameter as such (other than for built-in procedures).
The workarounds are:
1 To have the parameters in a list, which can vary in length and whose size can be checked.
2 To have the parameters always present.
3 Or to make the optional parameters globals.
Update (for completeness):
4 Eliminate the use of the optional parameter i.e. use a constant instead.

Stephen Lewkowicz (G1CMZ)
https://my.numworks.com/python/steveg1cmz
Visit this user's website Find all posts by this user
Quote this message in a reply
01-06-2018, 09:41 AM (This post was last modified: 01-06-2018 10:12 AM by Dieter.)
Post: #22
RE: epoch Prime
(01-06-2018 09:28 AM)salvomic Wrote:  
Code:
ti:=(epoch MOD 84600)/3600;
...
epoch2date(1515230706) returns {2018.0106, 12.41833333}
→HMS(12.41833333) returns 12°25'06'', that two hours later, but still I must set UTC problem...

It's not a timezone problem. Take a closer look at the quoted code line. ;-)

BTW the result is UTC, so if you want local time you'll have to add 3600 s to epoch at the beginning. Just as you subtract it at the end of the opposite conversion.

BTW2: Why do you return the time as 12,4183333333 instead of 12,2506? This doesn't take more than a simple h.ms conversion.

Or, if you want to return hours, minutes and seconds separately, you may do it this way:

seconds = epoch mod 86400
hh = IP(seconds/3600)
mm = IP(seconds mod 3600)/60)
ss = seconds mod 60

Edit: Or with "iquo" as mentioned by Didier:

seconds = epoch mod 86400
hh = iquo(seconds, 3600)
mm = iquo(seconds mod 3600, 60)
ss = seconds mod 60

Dieter
Find all posts by this user
Quote this message in a reply
01-06-2018, 09:50 AM
Post: #23
RE: epoch Prime
(01-06-2018 08:53 AM)Dieter Wrote:  BTW, does the Prime have a command for integer division? Like "DIV" or "\" in other programming languages?

iquo(Intgr1, Intgr2) returns the integer quotient of the Euclidean division of two integers.

(01-05-2018 11:26 PM)salvomic Wrote:  How to make an optional parameter to input (or not) the time zone in epoch()?
I would like to make a versatile function that accept optional parameters:

AFAIK it's not possible.
Find all posts by this user
Quote this message in a reply
01-06-2018, 10:46 AM
Post: #24
RE: epoch Prime
@Dieter. Don't you have the prime? Not even the app?

Good info about the optional parameters, although I suspected it. The workaround with a list in input is not bad.

For example:
{ "par1", val1, "par2", val2, ..... , "par_n", val_n}

if a "parX" is missing, one could assign a default value. It is a bit more clumsy to construct for the caller, but likely is doable.

Another way could be also with program wide values. (not necessarily globals)
But those may be persistent between calls so, a bit more tricky to handle.

Wikis are great, Contribute :)
Find all posts by this user
Quote this message in a reply
01-06-2018, 12:42 PM (This post was last modified: 01-06-2018 12:49 PM by Dieter.)
Post: #25
RE: epoch Prime
(01-06-2018 10:46 AM)pier4r Wrote:  @Dieter. Don't you have the prime? Not even the app?

No, Sir. 8-)

(01-06-2018 10:46 AM)pier4r Wrote:  Good info about the optional parameters, although I suspected it. The workaround with a list in input is not bad.

In this case I do not think that an optional parameter for the timezone is/was useful. When the function is called without the timezone parameter the user (who might be unaware of the timezone issue) has to remember that the result is UTC and not his local time. Or he may enter his local date/time and get a wrong epoch value returned. This may lead to confusion which is avoided if the timezone must be specified. Which I think is the best idea. For UTC this parameter is simply zero.

Dieter
Find all posts by this user
Quote this message in a reply
01-06-2018, 01:07 PM
Post: #26
RE: epoch Prime
(01-06-2018 12:42 PM)Dieter Wrote:  ...
In this case I do not think that an optional parameter for the timezone is/was useful. When the function is called without the timezone parameter the user (who might be unaware of the timezone issue) has to remember that the result is UTC and not his local time. Or he may enter his local date/time and get a wrong epoch value returned. This may lead to confusion which is avoided if the timezone must be specified. Which I think is the best idea. For UTC this parameter is simply zero.

Dieter

yes, I agree, Dieter, the time zone should be a needed parameter (0 for UTC), instead the date and time should be optional. Or we can decide to put 0 for "current date" (an time), or other date and time, as one or two parameters.

Thank also to other people for the advice.
I'll try to simplify again and to help the user to input seemless the parameters.
Later I'll put another try.

Salvo

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
01-06-2018, 02:45 PM (This post was last modified: 01-06-2018 02:59 PM by salvomic.)
Post: #27
RE: epoch Prime
nobody fo you said me that I made an "old error of mine": to use 84600 instead of 86400!
I made this error in some astronomical programs and then I was aware of the bug after ...days... :-(

Ok, this version should work, but with some caveat:
• epoch(da, ti, zone) : input -1 for current date and also for current time, zone: 0 UTC (GMT), 1, -1 and so on...; otherwise input time as 12°30'40'' and date as 2018.0106
• epoch2date(epoc, zone) : returns date and time (as HMS)
• epoch() is here always UTC, not local time even if the time in input is local.

Code:

// Epoch Unix time from 1970 Jan 1. Inspired by a Bill Duncan's program for HP-41CX
// Thanks to Dieter, Didier Lachieze, Stephen G1CMZ, pier4r...

// Epoch seconds in UTC time
// Input: da = date (i.e. 2018.0523), ti = time (i.e. 13°15'30''), zone UTC (0 GMT)
// -1 as current date and current time
EXPORT epoch(da,ti, zone)
BEGIN
IF da==-1 THEN da:=Date; END;
IF ti==-1 THEN ti:=Time; ELSE ti:=HMS→(ti); END;
ti:=ti-zone;
RETURN 86400*(DDAYS(1970.0101,da))+3600*HMS→(ti);
END;

EXPORT epoch2date(epoc, zone)
BEGIN
local da, ti;
epoc:=epoc+3600*zone;
da:=DATEADD(1970.0101, IP(epoc/86400));
ti:=(epoc MOD 86400)/3600;
RETURN({da, →HMS(ti)});
END;

Again, it would be better to have optional input, instead of remembering to put some "magic numbers" as -1 ...

Other help much appreciated Smile

Salvo

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
01-06-2018, 03:28 PM (This post was last modified: 01-06-2018 03:49 PM by pier4r.)
Post: #28
RE: epoch Prime
Little nitpick.

When one use constants, like 86400, at first it is ok to plaster them all over to get things done, but then (as you realized) a little typo may produce problems.

Disclaimer: I learned what I am going to write after having done, quintillions of times, the same actions I am going to criticize.

So a tip is: refactor them in (static) variables, maybe also with more than 2 letters for readability. When I see algorithms (especially long ones) that use quite unreadable names, while I appreciate the sharing effort since sharing is caring, I am not going to use them to understand what is going on. This because it is too much work to decode what they do if they are not commented and not easy to read. They are write only code.

I will do again my version unless I do not care what the algorithm is doing and I need only the result, then I will use the shared version.

Also comments (but comments are lacking in many algorithms seen in this forum so far, that's a pity). Comments documenting why such instructions are there, not how.

So something like:

Code:

//we can use up to 30 (!) chars in the variable names and function names.
LOCAL sec_in_day:=86400;
LOCAL sec_in_hour:=3600;
LOCAL unix_epoch_start_time:=1970.0101;

EXPORT epoch2date(epoch, zone)
//epoch
// - the number of seconds returned by the Unix timestamp
//zone
// - the timezone defined by the number of hours of difference from the UTC time.
BEGIN
LOCAL date_value, time_value;

//how comment (not that useful): update epoch adding the amount of seconds in an hour multiplied by the time zone difference.
//why comment: we need to align the epoch value to the defined timezone.
epoch:=epoch+sec_in_hour*zone;

date_value:=DATEADD(unix_epoch_start_time, IP(epoch/sec_in_day));
time_value:=(epoch MOD sec_in_day)/sec_in_hour;
RETURN({date_value, →HMS(time_value)}); 
END;

It may sound harsh, but it is not my intention. For me it is a pity to see shared code that seems minified and obfuscated unintentionally that then likely loses the chance to be picked and expanded by other members of the community.

Edit: of course, I assume you are typing your programs from a computer with a real keyboard. If you type them on the prime or on a touchscreen, I understand completely the short variables and the limited comments.

Wikis are great, Contribute :)
Find all posts by this user
Quote this message in a reply
01-06-2018, 03:45 PM (This post was last modified: 01-06-2018 04:16 PM by salvomic.)
Post: #29
RE: epoch Prime
(01-06-2018 03:28 PM)pier4r Wrote:  Little nitpick.

When one use constants, like 86400, at first it is ok to plaster them all over to get things done, but then (as you realized) a little typo may produce problems.

...

Edit: of course, I assume you are typing your programs from a computer with a real keyboard. If you type them on the prime or on a touchscreen, I understand completely the short variables and the limited comments.

yes, this last paragraph of your post is the real explanation of why most of us here use short vars and few comments...
I understand your thoughts and appreciate, however just now the program is still not finished, so the most important thing is if it works and how, then we can refactor variables and put in some other comments...
As I wrote in the first post, our goal is to make a program the more concise (and, if possible, as you wrote, the more user-friendly).

First of all we must solve some problems:
• to use less parameters (I mean reuse the parameters for date and time without "magic numbers" for the case in which the user wants to use the current date and time or he/she wants to input another date)
• to decide if it is important (or not so important) to give also "local time" epoch, or only (and always) GMT/UTC epoch (as it is now in the program).
• to decide if there is a reason to "complicate" the program, with calculation of leap seconds or other important considerations or not...

Salvo

EDIT:
as pier4r suggested, the version without "magic constants" it:
Code:

// Epoch Unix time from 1970 Jan 1. Inspired by a Bill Duncan's program for HP-41CX
// Thanks to Dieter, Didier Lachieze, Stephen G1CMZ, pier4r...

// Epoch seconds in UTC time
// Input: da = date (i.e. 2018.0523), ti = time (i.e. 13°15'30''), zone UTC (0 GMT)
// -1 as current date and current time
EXPORT epoch(da,ti, zone)
BEGIN
LOCAL sec_in_day:=86400;
LOCAL sec_in_hour:=3600;
LOCAL unix_epoch_start_time:=1970.0101;
IF da==-1 THEN da:=Date; END;
IF ti==-1 THEN ti:=Time; ELSE ti:=HMS→(ti); END;
ti:=ti-zone;
RETURN sec_in_day*(DDAYS(unix_epoch_start_time,da))+sec_in_hour*HMS→(ti);
END;

// Given an epoch and a time zone, the program returns date and time
EXPORT epoch2date(epoc, zone)
BEGIN
LOCAL sec_in_day:=86400;
LOCAL sec_in_hour:=3600;
LOCAL unix_epoch_start_time:=1970.0101;
local da, ti;
epoc:=epoc+sec_in_hour*zone;
da:=DATEADD(unix_epoch_start_time, IP(epoc/sec_in_day));
ti:=(epoc MOD sec_in_day)/sec_in_hour;
RETURN({da, →HMS(ti)});
END;

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
01-06-2018, 04:10 PM (This post was last modified: 01-06-2018 06:09 PM by salvomic.)
Post: #30
RE: epoch Prime
Another question:
epoch2date() in Home return time like 17°07'11'', but in CAS only like 17.11972222
But we know that input HMS (17°07'11'') is intended to be used only in Home...

Any workaround?

Salvo

EDIT:
I'll put here code and probable new versions.

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
01-06-2018, 06:26 PM (This post was last modified: 01-06-2018 06:27 PM by Dieter.)
Post: #31
RE: epoch Prime
(01-06-2018 02:45 PM)salvomic Wrote:  nobody fo you said me that I made an "old error of mine": to use 84600 instead of 86400!
I made this error in some astronomical programs and then I was aware of the bug after ...days... :-(

What? Nobody told you? Sure I did! Didn't you read my post?

(01-06-2018 09:41 AM)Dieter Wrote:  
(01-06-2018 09:28 AM)salvomic Wrote:  
Code:
ti:=(epoch MOD 84600)/3600;
...
epoch2date(1515230706) returns {2018.0106, 12.41833333}
→HMS(12.41833333) returns 12°25'06'', that two hours later, but still I must set UTC problem...

It's not a timezone problem. Take a closer look at the quoted code line. ;-)

"Take a closer look at the quoted code line" – wasn't this clear enough?

(01-06-2018 02:45 PM)salvomic Wrote:  Again, it would be better to have optional input, instead of remembering to put some "magic numbers" as -1 ...

I think it's better that the timezone is not optional but required. And this "magic" number is not that magic – it's simply your local timezone. We can safely assume that virtually everyone who uses such a program for converting date and time is aware of his local timezone.

Dieter
Find all posts by this user
Quote this message in a reply
01-06-2018, 06:54 PM (This post was last modified: 01-06-2018 07:36 PM by StephenG1CMZ.)
Post: #32
RE: epoch Prime
A liitle coding tip...

Using -1 as a flag for now is not recommended, but not just because -1 is a "magic number". Magic numbers make the code difficult to maintain, but the code still works.

No, it is much worse than that. It encourages you to write code like
Epoch(-1)
And changing that to
Rightnow:=-1 //magic number
Epoch(Rightnow) //no magic number
Is little better.

On its own in a program that does nothing but calculate epoch it looks and works fine.

Now consider
Result1:=Epoch(-1) // what is the time now
Result2:=VoyagerPosition(-1) // where is Voyager now

This will probably work well for weeks, until one day you can't find Voyager...

What happened is:
Epoch(Monday)
//midnight
VoyagerPosition(Tuesday)
And Result1 and Result2 are wrong by 1 day or 24h.

Another potential problem is that the Get Date code is duplicated in both procedures...so if the Prime OS changes, only one instance of the code might be changed...or even none, since it is not obvious that either procedure needs to discover Now, rather than just use a date. (Historically the Time/Teval procedure has changed on the Prime).

A much better solution is to keep the discovery of Now separate from the other code that works with any date, thus:

Code:

Now()
Begin
  Get System date/time, possibly changing format to match Epoch input etc.
End
JustNow:=Now()
Epoch(JustNow)
//midnight
VoyagerPosition(JustNow)//same date!!!
So from a practical viewpoint, user code using this procedure may be more reliable, and from a theoretical viewpoint the functions to calculate the epoch of a date and to discover Now are cleanly separated.

Of course, when putting together something that works, and checking that your algorithm works well enough, it is easy to forget that your code might not be used alone, and might be operating with other procedures, which might also be calculating now, but differently.

Stephen Lewkowicz (G1CMZ)
https://my.numworks.com/python/steveg1cmz
Visit this user's website Find all posts by this user
Quote this message in a reply
01-06-2018, 07:58 PM (This post was last modified: 01-06-2018 08:04 PM by salvomic.)
Post: #33
RE: epoch Prime
(01-06-2018 06:26 PM)Dieter Wrote:  What? Nobody told you? Sure I did! Didn't you read my post?
Sorry Dieter, I had closed eyes Sad - and thanks you! ;-)

(01-06-2018 06:26 PM)Dieter Wrote:  I think it's better that the timezone is not optional but required. And this "magic" number is not that magic – it's simply your local timezone. We can safely assume that virtually everyone who uses such a program for converting date and time is aware of his local timezone.
Dieter

I meant "magic number" for data and time, as is not easy to get optional arguments... Not for timezone: for that I thought to put 0, UTC, not 1 (my time zone)... However I'll agree to make timezone not optional.
I would like to eliminate soon that "magic numbers", but also to offer the user the option to input his preferred data or the current one, without make two different functions...

So, how to do better?

(01-06-2018 06:54 PM)StephenG1CMZ Wrote:  A liitle coding tip...

Using -1 as a flag for now is not recommended, but not just because -1 is a "magic number". Magic numbers make the code difficult to maintain, but the code still works.
yes, I know, but, as I said, if it is not possible to get optional arguments, I must "invent" something to do ;-)
(01-06-2018 06:54 PM)StephenG1CMZ Wrote:  Another potential problem is that the Get Date code is duplicated in both procedures...so if the Prime OS changes, only one instance of the code might be changed...or even none, since it is not obvious that either procedure needs to discover Now, rather than just use a date. (Historically the Time/Teval procedure has changed on the Prime).
A much better solution is to keep the discovery of Now separate from the other code that works with any date,
I agree. Effectively I should rewrite that code in that way...
(01-06-2018 06:54 PM)StephenG1CMZ Wrote:  Of course, when putting together something that works, and checking that your algorithm works well enough, it is easy to forget that your code might not be used alone, and might be operating with other procedures, which might also be calculating now, but differently.

and you are right: I too want to offer a code that's usable also in other programs as input.
So, I'm reading again your, Dieter's and other post with advise, and I'm here to have other help by you all to make better the code, however without "complicate" it too much...

Salvo

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
01-06-2018, 08:26 PM
Post: #34
RE: epoch Prime
(01-06-2018 06:26 PM)Dieter Wrote:  
(01-06-2018 02:45 PM)salvomic Wrote:  nobody fo you said me that I made an "old error of mine": to use 84600 instead of 86400!
I made this error in some astronomical programs and then I was aware of the bug after ...days... :-(

What? Nobody told you? Sure I did! Didn't you read my post?

(01-06-2018 09:41 AM)Dieter Wrote:  It's not a timezone problem. Take a closer look at the quoted code line. ;-)

"Take a closer look at the quoted code line" – wasn't this clear enough?

(01-06-2018 02:45 PM)salvomic Wrote:  Again, it would be better to have optional input, instead of remembering to put some "magic numbers" as -1 ...

I think it's better that the timezone is not optional but required. And this "magic" number is not that magic – it's simply your local timezone. We can safely assume that virtually everyone who uses such a program for converting date and time is aware of his local timezone.

Dieter

I would not be so confident that people know there own timezone...
I know what it is right now, yes, but at some times of the year I wouldn't be sure what it would be next week. Have the clocks gone +1 or -1? Is that this weekend or next that daylight is saved? It might have saved daylight, but on at least one occasion it cost me breakfast Smile
And summertime in Europe happens/used to happen/ on a different weekend than in the uk, so if you travel 40 km on the wrong week the time difference can jump between 0-2 hours.

That issue with the wrong constant reminds me of a time I was debugging some astronomical code that seemed to show that it took light 9 minutes to reach us, rather than the expected 8.
I was beginning to suspect an error in my constants.
I rigorously checked the degrees/radians conversion factor at least twenty times, and every decimal digit was correct. Eventually I realized it was a non-decimal digit that was wrong: 157.xxx instead of 57.xxx

It is so easy to read what you expect to see.

Surely it is time that technology only allowed constants to be copied, rather than typed in??? Wink

Stephen Lewkowicz (G1CMZ)
https://my.numworks.com/python/steveg1cmz
Visit this user's website Find all posts by this user
Quote this message in a reply
01-06-2018, 08:37 PM
Post: #35
RE: epoch Prime
(01-06-2018 08:26 PM)StephenG1CMZ Wrote:  I would not be so confident that people know there own timezone...

The average person – yes. But a Unix user who is used to handling UTC times?

(01-06-2018 08:26 PM)StephenG1CMZ Wrote:  I rigorously checked the degrees/radians conversion factor at least twenty times, and every decimal digit was correct. Eventually I realized it was a non-decimal digit that was wrong: 157.xxx instead of 57.xxx

That's why I prefer defining such constants as "180/pi". Or "24*60*60" instead of 86400. ;-)

(01-06-2018 08:26 PM)StephenG1CMZ Wrote:  It is so easy to read what you expect to see.

And that's why proofreading usually is done by another person.

Dieter
Find all posts by this user
Quote this message in a reply
01-06-2018, 08:45 PM
Post: #36
RE: epoch Prime
speking of the opportunity to give optional parameters, it would be desirable to have in HPPPL a syntax like this:
Code:

EXPORT epoch(dat=Date,tim=Time, zone=0)

In this code if the user doesn't input a date, the program use the system defined Date or if he/she doesn't input a zone, the program use 0 as value...

Something like that could make our epoch program more simple to do ;-)

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
01-06-2018, 08:59 PM
Post: #37
RE: epoch Prime
(01-06-2018 08:45 PM)salvomic Wrote:  speking of the opportunity to give optional parameters, it would be desirable to have in HPPPL a syntax like this:
Code:
EXPORT epoch(dat=Date,tim=Time, zone=0)

If the user enters two parameters out of three, how should the program know which two are meant? Does epoch(2015.0327, 1) mean that the time is 1:00 or that the timezone is UTC+1 ?

Maybe something like epoch(2015.0327, , 1) could be less ambiguous (if it was possible). But would this be an advantage in terms of intuitive use of the epoch() function?

Dieter
Find all posts by this user
Quote this message in a reply
01-06-2018, 09:01 PM (This post was last modified: 01-06-2018 09:40 PM by salvomic.)
Post: #38
RE: epoch Prime
(01-06-2018 08:59 PM)Dieter Wrote:  ...
Maybe something like epoch(2015.0327, , 1) could be less ambiguous (if it was possible). But would this be an advantage in terms of intuitive use of the epoch() function?

Dieter

I don't know if it would be an advantage, but yes, I meant this syntax: epoch(,,2) to say "current date and time and timezone +2".

As that syntax there isn't still, maybe we should use a list to simulate it...

EDIT:
or we simply could ignore that problem and only say to the user (for now with comments, but for problems like that I do hope a real *user help* system for HPPPL programs!) that it can use this simple syntax, using the system variables Date and Time...
Code:
epoch(Date, Time, timezone)
to get current date and time, and to choose only his time zone.
In this link there is the simplified version of the program.

What do you think about?

Salvo

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
01-06-2018, 09:59 PM (This post was last modified: 01-06-2018 09:59 PM by pier4r.)
Post: #39
RE: epoch Prime
(01-06-2018 08:37 PM)Dieter Wrote:  And that's why proofreading usually is done by another person.

Tips if your are "solo".

1. Rubberducking. Tell out loud to a rubber duck what is your code doing. Or even better, register yourself as if you would release a youtube video explaining your code. (the registration can be just an audio). Seems stupid, but do it! it works. There are people that share development sessions on twitch. It seems crazy, but the motivation of showing some work to someone else is enough to keep them going.

2. Point and read. Point (with a finger) the code/writing and read it.

3. change font (size, typeface) when you proof read, or the background color. It seems crazy but it works.

4. paper debug. Like the old days. give an input to your code and go through it manually.

Wikis are great, Contribute :)
Find all posts by this user
Quote this message in a reply
01-06-2018, 10:07 PM
Post: #40
RE: epoch Prime
(01-06-2018 09:59 PM)pier4r Wrote:  ...
4. paper debug. Like the old days. give an input to your code and go through it manually.

I would like to do so, and sometimes I do it truly, but mostly I don't find time to write or I don't find ...paper. Smile
However it works!

Salvo

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)