On "=." in scripts: I never thought of using =: because it's easy to set a
stop in a script if I want to examine those local values and this also
allows access to everything else in the function context without changing
any code. For example:
13!:3 'J2StdCvtNums 0 4 6 9 10 11 12 17 21 22 24 26 28' *NB. Set stop
lines*
13!:0]1 *NB. Halt on interrupt*
'S' J2StdCvtNums _3.14 6.02e_23 *NB. Convert J numbers to std rep*
-3.1400000000000001 0.0000000000000000 *NB. Didn't stop - why?*
13!:3 'J2StdCvtNums *:* 0 4 6 9 10 11 12 17 21 22 24 26 28' *NB. Dyadic
stops*
'S' J2StdCvtNums _3.14 6.02e_23
|stop: J2StdCvtNums
| 'S'=x
|J2StdCvtNums[:0]
13!:4'' *NB. Resume execution from current line.*
|stop
| ' '={.,y
|J2StdCvtNums[:0] NB. Same line because multiple statements.
13!:4''
|stop
| toStd=.-.'J'-:''$'2'-.~,x
|J2StdCvtNums[:4]
13!:0]0 *NB. Exit debug*
13!:0]1 NB. Halt on interrupt
On Wed, Apr 18, 2018 at 6:21 PM, Henry Rich <[email protected]> wrote:
> On =: in scripts: When I replace =. with =: for debugging purposes, I
> always precede it with 2 spaces:
>
> name =: value
>
> Then after testing a global replace of ' =:' with '=.' removes the global
> assignments.
>
> Henry Rich
>
>
> On 4/18/2018 6:16 PM, Marshall Lochbaum wrote:
>
>> This is a perfectly good use of the forums in my book. At the very
>> least, we've had similar posts before and no one's complained.
>>
>> Overall your program looks pretty good to me. It's not leveraging the
>> Full Power of J™, but it's a great start. You know what I. does!
>>
>> There are some ways to use arrays to do more of your work for you. You
>> write
>>
>> 'minCut maxCut' =. x
>> ...
>> minWanted =: (<.minCut*#srtData){srtData
>> maxWanted =: (<.maxCut*#srtData){srtData
>>
>> but this is the same as
>>
>> 'minWanted maxWanted' =: (<.x*#srtData){srtData
>>
>> since each of * <. and { has rank zero, that is, maps over arrays, on
>> the side of x. (Unrelatedly, these should probably use =. rather than =:
>> to avoid global assignment. It looks like they might have been =: for
>> debugging, but if so, it's good practice to look over the code again and
>> change them back when you're done.)
>>
>> A more sophisticated example is the plane-scaling code in displayFits.
>> You use different code for each different number of scalings to do:
>>
>> r =. minmax scaleT2D 0{imarray
>> select. 3<.{.$imarray NB. use up to 3 planes
>> case. 3 do.
>> g =. minmax scaleT2D 1{imarray
>> b =. minmax scaleT2D 2{imarray
>> case. 2 do.
>> b =. minmax scaleT2D 1{imarray
>> g =. -: r+b NB. average of red and blue
>> case. 1 do.
>> 'g b'=. r;r
>> end.
>>
>> Instead, you could do all the scalings in one go:
>> ((#imarray) is like ({.$imarray), but it is a scalar and not a vector.)
>>
>> numScales =. 3<.#imarray NB. use up to 3 planes
>> scaled =. minmax scaleT2D"_ _1 numScales {. imarray
>> if. numScales < 3 do.
>> avg =. (+/ % #) scaled
>> scaled =. scaled , (3-numScales)#,:avg
>> end.
>> 'r g b' =. scaled
>>
>> This example first uses scaleT2D with an explicit rank to operate on
>> each of the first numScales planes. If you're not familiar with it, my
>> favorite explanation of the rank conjunction (") is
>> http://www.jsoftware.com/help/jforc/loopless_code_i_verbs_have_r.htm.
>> A rank of (_ _1), that is, infinity on the left and minus one on the
>> right, means to apply the function to the entire left argument and each
>> subarray of the right argument, effectively mapping over only the right
>> argument. I could have used a rank of 2 rather than _1 on the right, but
>> rank _1 is more flexible--it would work even if the planes were instead
>> three-dimensional.
>>
>> After this compuation, scaled is a three-dimensional array of the first
>> numScales planes of imarray. The average of its planes can be found with
>> the standard averaging function (+/ % #), which happens to be the
>> canonical example of a fork. If you're interested, these are described
>> at http://code.jsoftware.com/wiki/Vocabulary/fork.
>>
>> An exponent like (2^8) unfortunately always evaluates to a
>> floating-point number. I habitually use (<.@^) when I know the arguments
>> are integers to avoid accidentally promoting to floats.
>>
>>
>> I actually gave a talk on a task similar to the parsing you do here. My
>> task was to parse the header of a simple wave file. A script version
>> (there's no recording that I'm aware of) is at
>> http://code.jsoftware.com/wiki/Community/Conference2014/Talk
>> s/UsingDataAsCode
>> and the current script that I use based on this is
>> https://github.com/mlochbaum/JSound/blob/master/wav.ijs.
>> This is certainly difficult material for a beginning J programmer, but
>> the techniques discussed in the talk might be useful for you as you gain
>> more skill.
>>
>> One neat trick similar to the one used there: rather than write
>>
>> bitpix =. hdata getHdrVal 'BITPIX'
>> naxis =. hdata getHdrVal 'NAXIS'
>> naxis1 =. hdata getHdrVal 'NAXIS1'
>> naxis2 =. hdata getHdrVal 'NAXIS2'
>> naxis3 =. hdata getHdrVal 'NAXIS3'
>>
>> you might use
>>
>> fields =. ;: 'BITPIX NAXIS NAXIS1 NAXIS2 NAXIS3'
>> (fields) =. hdata&getHdrVal&.> fields
>>
>> and then the fields will be defined in variables BITPIX, etc.
>>
>> Another very cool trick that I found after the talk would be useful
>> here:
>>
>> select. bitpix
>> case. _32 do. adata =. (naxis3,naxis2,naxis1)$ |. _1 fc |.
>> rdata
>> case. _64 do. adata =. (naxis3,naxis2,naxis1)$ |. _2 fc |.
>> rdata
>> case. 16 do. adata =. (naxis3,naxis2,naxis1)$ |. _1 ic |.
>> rdata
>> case. 32 do. adata =. (naxis3,naxis2,naxis1)$ |. _2 ic |.
>> rdata
>> end.
>>
>> The idea is to make an adverb (mine is audioconvert in wav.ijs) which
>> takes a format specification like bitpix and returns a conversion
>> function. Something like:
>>
>> rawconvert =: 1 : 0
>> select. u
>> case. _32 do. _1&fc
>> case. _64 do. _2&fc
>> case. 16 do. _1&ic
>> case. 32 do. _2&ic
>> case. do. 'Invalid format' assert 0
>> end.
>> )
>>
>> which can then be called with
>>
>> cvt =. bitpix rawconvert NB. A conversion function
>> adata =. (naxis3,naxis2,naxis1)$ |. cvt |. rdata
>>
>> Now the really cool thing is that J knows how to invert each of these
>> functions. So when you want to store the data again, you just use
>> (cvt^:_1)! This is a J-only technique: I don't know of any other
>> language that has the functional capabilities and the automatic
>> inversion required to do it.
>>
>> There's always more to say but I think that's enough for one email. Good
>> luck with your future J projects!
>>
>> Marshall
>>
>> On Wed, Apr 18, 2018 at 02:47:02PM -0400, Thomas Hickey wrote:
>>
>>> As one of my first J programs, I've written a minimal viewer for FITS
>>> files, the standard way of sharing astronomical data, especially images.
>>>
>>> I'd appreciate it if someone could take a look at it and let me know how
>>> the code (80 lines of J) looks. I know I've replaced some really awkward
>>> code in it, so I imagine there are better ways of doing lots of things.
>>>
>>> The code is on GitHub at https://github.com/ThomasBHickey/JFits, along
>>> with a sample FITS file in the fitsSample folder. Pointers on
>>> organizing J
>>> code on GitHub would be appreciated as well.
>>>
>>> Or is there a better way to accomplish this than the programming forum?
>>> I
>>> know this is longer than most of the questions that are posted here, but
>>> I
>>> think it is an interesting application of J.
>>>
>>> --Th
>>> ----------------------------------------------------------------------
>>> For information about J forums see http://www.jsoftware.com/forums.htm
>>>
>> ----------------------------------------------------------------------
>> For information about J forums see http://www.jsoftware.com/forums.htm
>>
>
>
> ---
> This email has been checked for viruses by AVG.
> http://www.avg.com
>
>
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
--
Devon McCormick, CFA
Quantitative Consultant
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm