question about exercise D-7 in Legrand's book

Learning APL or new to Dyalog? Ask "silly" questions here, without fear...

question about exercise D-7 in Legrand's book

Postby haupz on Sat Jul 14, 2018 8:36 am


first post. Thanks for having me. Noob alert. :-)

I'm making my way through Bertrand Legrand's "Mastering Dyalog APL" book, and have a question about exercise D-7.

The task is to write a monadic function that puts a frame around a text matrix.

The solution given in the book appears to be wrong. It will not frame the
matrix as given in the text, i.e.,

Code: Select all
|ab |
|a  |

but instead like this:

Code: Select all
+ -   +
| ab  |
| a   |
| abc |
+ -   +

There are two problems with this:

1. There isn't a correct amount of minus signs because a single minus sign is prepended and appended, instead of a number of minus signs that corresponds to the number of characters in the longest string in the text matrix.

2. The left and right boundaries are added as extra columns rather than being prepended and appended to the individual text lines.

I'm unsure about how to achieve the intended solution. Concretely,

* How do I get the number of minus signs right? (Need to get the maximum length of the strings in the matrix - how to do that?)

* How do I prepend and append to individual elements in the matrix, rather than prepend and append columns? (Prepend and append columns first, then ravel by row?)

Grateful for any pointer and hint,

Posts: 10
Joined: Mon Jul 02, 2018 7:28 am

Re: question about exercise D-7 in Legrand's book

Postby Phil Last on Sat Jul 14, 2018 2:49 pm

I assume your text "matrix" is formed something like
      3 1⍴'ab' 'a' 'abc'
      ⍪'ab' 'a' 'abc'

Either by applying the "format" (⍕) function to it or by creating is as
      ↑'ab' 'a' 'abc'
      3 3⍴'ab a  abc'
it will become a "simple" two dimensional array wherein each row is padded with blanks making them all the same length.

I also assume you are using the "above" (⍪) or (,[⎕IO]) function to catenate the hyphens. With a simple array and a "scalar" (the single hyphen), "above" will use "scalar extension" to replicate the hyphen to the correct number. e.g.
      '-'⍪2 5⍴'thesewords'
User avatar
Phil Last
Posts: 557
Joined: Thu Jun 18, 2009 6:29 pm

Re: question about exercise D-7 in Legrand's book

Postby Brian|Dyalog on Sat Jul 14, 2018 6:20 pm

Hi Michael!

Thanks for posting your question and welcome to the world of APL!

To follow up on what Phil posted...

There's a difference between a matrix where every element is a simple scalar element and a matrix of vectors. I'll use the Frame function as written in D-7 in Mastering Dyalog APL.

Here's the simple matrix output...
      Frame mat←3 4⍴⎕A

And here's the matrix of character vectors output...
      Frame matofvecs←3 1⍴↓3 4⍴⎕A
+ - +
| ABCD |
| EFGH |
| IJKL |
+ - +

There are a few ways to tell the difference...

The shapes are different...
3 4
3 1

Their depths (the level of nesting) are different...

There's a user command (]boxing) that you can use to better see the structure of arrays.
      ]boxing on

I hope this helps and keep asking questions!
User avatar
Posts: 102
Joined: Thu Nov 26, 2009 4:02 pm
Location: West Henrietta, NY

Re: question about exercise D-7 in Legrand's book

Postby haupz on Sun Jul 15, 2018 10:48 am

Hi Brian, Phil,

thank you both for your insightful responses. They made clear to me that the shape of data really matters a lot, and that there is a crucial (if visually subtle) difference between matrices of character vectors, and matrices of character scalars.

With that help, I was able to appreciate the book's default solution. I still felt challenged to provide a solution that would work for my (wrongly assumed) use case of having to frame a 1-column matrix of character vectors.

I've documented the somewhat naïve and brutish results here: ... D-7.dyalog - and note that I also tried to cover special cases such as N-by-1 matrices of character scalars.

For reading convenience, the answer to the final question in exercise D-7 is here (the reasoning is in the GitHub repo):

Code: Select all
∇ FramedText ← Frame2 Text;nr;nc
    FramedText ← ⊃ (2 ⍴ (↑,Text) Text)[2 ⌊ (⍴Text)[2]]
    FramedText ← ⊃ (2 ⍴ (((⍴FramedText),1)⍴FramedText) FramedText)[⍴⍴FramedText]
    FramedText ← (⎕UCS 9472),[1]FramedText,[1](⎕UCS 9472)
    FramedText ← (⎕UCS 9474),[2]FramedText,[2](⎕UCS 9474)
    nr nc ← ⍴FramedText
    FramedText[(1 1) (1 nc) (nr 1) (nr nc)] ← ⎕UCS 9484 9488 9492 9496

Feel free to tear it apart. I feel a bit uncomfortable about the two first lines in the function that do all the conditional selection. Not sure how idiomatic that is.

Thanks again, this was fun. :-)


Posts: 10
Joined: Mon Jul 02, 2018 7:28 am

Return to New to Dyalog?

Who is online

Users browsing this forum: No registered users and 1 guest