How to extract all the car's from the elements of a list-of-lists? - audacity

If I create several empty labels on an Audacity 2.4.2 audio track (by clicking at various points along the track, and pressing Ctrl-B after each click), the Nyquist Prompt evaluates the expression
(cadar (aud-get-info "Labels"))
...to a list L whose elements are, in turn, 3-element sublists.
For the sake of this description, I will refer to these 3-element sublists as "triples".
As it happens, for each of these triples, the first two elements are identical floating point numbers, and last element is the empty string.
Thus, a typical instance of such a list L may begin with something like
((0.12345 0.12345 "") (6.78901 6.78901 "") (23.45678 23.45678 "") ...
How can I create a new list consisting of all the first elements of such a list L?
For example, if my initial list L begins as shown above, what Nyquist expression involving the list L will evaluate to a list beginning as shown below?
(0.12345 6.78901 23.45678 ...)
(I tried stuff like (mapc (lambda (x) x) (cadar (aud-get-info "Labels"))), which not only failed to produce the desired result, but in some cases actually caused the addition of several new labels to the track, something I find completely bewildering. Therefore, as strange as this may sound, I must stress that I am looking for solutions that leave the original interface unchanged, and, in particular, do not add any new labels the currently selected track.)

I'm using the current Audacity 3.1.3 version, but this should all be the same for Audacity 2.4.2.
In the Nyquist Prompt, if you run with the Debug button:
(print (aud-get-info "Labels"))
You will see an output similar to:
((1 ((0.184322 0.184322 "") (0.654661 1.24576 "") (2.25424 2.25424 ""))))
The first "1" is the track number (zero indexed).
If there are two label tracks, it will look something like:
((1 ((0.184322 0.184322 "") (0.654661 1.24576 "") (2.25424 2.25424 "")))
(3 ((0.449153 0.449153 ""))))
Each label is in the form:
(start-time end-time "Label text")
(Observe that the second label in track 1 is a region label.)
Thus the format of the data returned by (aud-get-info "Labels") is in the form:
(list (list track-num (list (first-label) (second-label) ...))
(list track-num (list (first-label) ...)))
To get a list of labels from each track:
(let ((label-info (aud-get-info "Labels")))
(dolist (track label-info)
(print (second track))))
which, in the above case, will print to the Debug window:
((0.184322 0.184322 "") (0.654661 1.24576 "") (2.25424 2.25424 ""))
((0.449153 0.449153 ""))
To create a list of each label start times:
(let ((output-list ())
(label-info (aud-get-info "Labels")))
(dolist (track label-info) ;step through each track in label-info
(setf labels (second track))
(dolist (label labels) ;step through each label in labels
(setf start-time (first label))
(push start-time output-list)))
;; Print the list:
(format nil "~a" output-list))
Which, in the above example. prints:
(0.449153 2.25424 0.654661 0.184322)

Related

Take every item in list that starts with x and put it in a new list - Rego

list := ["a:aqsdf", "a:asdf", "b:gfs", "b:sdf", "a:adfd", "b:asdfd"]
I want the new list to only include items that start with 'a': ["a:aqsdf", "a:asdf", "a:adfd"]
I've tried working with sets with no success. This would be a breeze in python but can't seem to wrap my head around rego. I can turn it into a set but not sure how to squeeze in an if statement(startswith(list[_], "a") == true)
One way to do this is with an array comprehension and the startswith builtin function:
[ x | x := list[_]; startswith(x, "a")]
Playground example: https://play.openpolicyagent.org/p/8mQYYvUL2h
This is essentially saying to define a new array containing the value of x if the rule body is true. The rule body for the comprehension is in turn iterating over all indicies of list for values of x, and will be true when the value of x starts with "a".
References:
https://www.openpolicyagent.org/docs/latest/policy-reference/#strings
https://www.openpolicyagent.org/docs/latest/policy-language/#comprehensions

Erlang list comprehension, once again

I'm trying to get a list comprehension working, which intention is to verify that each element X in List is followed by X+Incr (or an empty list). Later, I shall use that list and compare it with a list generated with lists:seq(From,To,Incr).
The purpose is to practice writing test cases and finding test properties.
I've done the following steps:
1> List.
[1,3,5,8,9,11,13]
2> Incr.
2
3> List2=[X || X <- List, (tl(List) == []) orelse (hd(tl(List)) == X + Incr)].
[1]
To me, it seem that my list comprehension only takes the first element in List, running that through the filter/guards, and stops, but it should do the same for EACH element in List, right?
I would like line 3 returning a list, looking like: [1,2,9,11,13].
Any ideas of how to modify current comprehension, or change my approach totally?
PS. I'm using eqc-quickcheck, distributed via Quviq's webpage, if that might change how to solve this.
The problem with your list comprehension is that List always refers to the entire list. Thus this condition allows only those X that are equal to the second element of List minus Incr:
(hd(tl(List)) == X + Incr)
The second element is always 3, so this condition only holds for X = 1.
A list comprehension cannot "look ahead" to other list elements, so this should probably be written as a recursive function:
check_incr([], _Incr) ->
true;
check_incr([_], _Incr) ->
true;
check_incr([A, B | Rest], Incr) ->
A + Incr == B andalso check_incr([B | Rest], Incr).
Maybe I'm misunderstanding you, but a list comprehension is supposed to be "creating a list based on existing lists". Here's one way to generate your list using a list comprehension without using lists:seq:
> Start = 1, Inc = 2, N = 6.
6
> [Start + X*Inc || X <- lists:seq(0,N)].
[1,3,5,7,9,11,13]
You could do something like this:
> lists:zipwith(fun (X, Y) -> Y - X end, [0 | List], List ++ [0]).
[1,2,2,2,2,2,2,-13]
Then check that all elements are equal to Incr, except the first that should be equal to From and the last that should be greater or equal than -To.
One quick comment is that the value List does NOT change when in the comprehension is evaluated, it always refers to the initial list. It is X which steps over all the elements in the list. This means that your tests will always refer to the first elements of the list. As a list comprehension gives you element of a list at a time it is generally not a good tool to use when you want to compare elements in the list.
There is no way with a list comprehension to look at successive sublists which is what you would need (like MAPLIST in Common Lisp).

Need advice on how to print a matrix in lisp

I have a matrix defined so if I do this
(format t "~a" (get-real-2d 0 0))
it prints out the element in the first row first column
and if I do this
(format t "~a" (get-real-2d a 0 1))
it prints out the element in first row second column
and if I do this
(format t "~a" (get-real-2d a 1 0))
it prints out the element in second row first column.
The matrix a looks like this
a =
((0 1 2)
(3 4 5)
(6 7 8))
and I was hoping you can show me exactly how to write a dotimes loop or other loop
that would in as few lines as possible would print out the matrix using the get-real-2d function so the output looks like this:
0 1 2
3 4 5
6 7 8
I'm just hoping you can show me a slick loop that would be real small that I can use to print matrices that I can use in my lisp library something real professional looking, like one that would use only variables. Something like:
(format t "~a" (get-real-2d i j))
instead of a bunch of:
(format t "~a" (get-real-2d 0 0))
(format t "~a" (get-real-2d 0 1))
(format t "~a" (get-real-2d 0 2))
;;;;LATEST EDIT;;;
to make this simple I call
(defparameter a (create-mat 3 3 +32fc1+))
to create a 3x3 matrix - create-mat is a wrapper for opencv's cvCreateMat
the output from that command at repl is
(defparameter a (create-mat 3 3 +32fc1+))
A
CL-OPENCV> a
#.(SB-SYS:INT-SAP #X7FFFD8000E00)
i/e the variable a is a pointer to the 3x3 matrix
then I run
(defparameter data (cffi:foreign-alloc :float :initial-contents
'(0.0f0 1.0f0 2.0f0 3.0f0 4.0f0 5.0f0 6.0f0 7.0f0 8.0f0)))
to create the data for the matrix - which I next will allocate to the matrix
the output from that command at repl is
CL-OPENCV> (defparameter data (cffi:foreign-alloc :float :initial-contents
'(0.0f0 1.0f0 2.0f0 3.0f0 4.0f0 5.0f0 6.0f0 7.0f0 8.0f0)))
DATA
CL-OPENCV> data
#.(SB-SYS:INT-SAP #X7FFFD8000E40)
i/e the variable a is data pointer to the data ill add to the matrix
then I call..
(set-data a data 12) to add the data to the matrix - set-data is a wrapper for opencv's cvSetData
so now when I run - (get-real-2d is a wrapper for opencv's cvGetReal2d)
(get-real-2d a 0 0) it gets the element of matrix a at row 0 col 0 which is 0.0d0
the output from that command at repl is
CL-OPENCV> (get-real-2d a 0 0)
0.0d0
and now when I run
(get-real-2d a 0 1) it gets the element of matrix a at row 0 col 1 which is is 0.0d0
the output from that command at repl is
CL-OPENCV> (get-real-2d a 0 1)
1.0d0
and when I run this loop
(dotimes (i 3)
(dotimes (j 3)
(format t "~a~%" (get-real-2d a i j))))
the output from that command at repl is
CL-OPENCV> (dotimes (i 3)
(dotimes (j 3)
(format t "~a~%" (get-real-2d a i j))))
0.0d0
1.0d0
2.0d0
3.0d0
4.0d0
5.0d0
6.0d0
7.0d0
8.0d0
NIL
but when I try your method #Svante
(dotimes (i 3)
(dotimes (j 3)
(format t "~{~{~a~^ ~}~%~}" (get-real-2d a i j))))
I get error:
The value 0.0d0 is not of type LIST.
[Condition of type TYPE-ERROR]
because the output of 1 run of get-real-2d is just a 1 number float i/e
CL-OPENCV> (get-real-2d a 0 0)
0.0d0
with that info can you help me print the matrix so it looks like this
0.0d0 1.0d0 2.0d0
3.0d0 4.0d0 5.0d0
6.0d0 7.0d0 8.0d0
You can do that directly in the format directive. The format instructions ~{ and ~} descend into a list structure.
(format t "~{~{~a~^ ~}~%~}" matrix)
The outer pair of ~{ ~} loops over the first level of the matrix, so that the directives inside get to see one row at a time. The inner pair of ~{ ~} loops over each such row, so that the directives inside get to see one element at a time. ~A prints that element. The part between ~^ and ~} gets printed only between executions of the loop body, not at the end. ~% emits a #\Newline.
EDIT as requested
Note that the ~{ ~} replace the looping, and that I named the variable matrix, not element. You need to put the entire matrix there, and it is supposed to be in the form of a nested list. I deduced this from your statement that a is ((0 1 2) (3 4 5) (6 7 8)). So, (format t "~{~{~a~^ ~}~%~}" a).
If the matrix happens not to be in the form of a nested list but rather some kind of array, you really need to loop over the indices. Nested dotimes forms should be sufficient at first:
(fresh-line)
(dotimes (i (array-dimension array 0))
(dotimes (j (array-dimension array 1))
(format t "~a " (aref array i j)))
(terpri))
I don't know how your matrices map to arrays, so you will have to replace array-dimension and aref with your versions.
Your question can be understood in two ways, and that is why it has two solutions:
Define method for printing object of type matrix (in this case it may use the knowledge about the internal structure of matrix):
(defmethod print-object ((matrix matrix) stream)
(format stream "~{~{~a~^ ~}~%~}" matrix))
Using format as is shown in the answers.
Define client function that can use the only method of your object - get-real-2d:
(defun print-matrix (matrix dimension-x dimension-y)
(dotimes (x dimension-x)
(dotimes (y dimension-y)
(princ (get-real-2d matrix x y))
(princ #\Space))
(princ #\Newline)))
Just using dotimes.
Here are just the two dotimes loops that you were asking for. The only thing that you need to pay attention for is when to print spaces and when to print newlines.
(dotimes (i 3)
(dotimes (j 3)
(princ (get-real-2d a i j))
(if (< j 2)
(princ #\Space)
(terpri))))
Alternatively, you might want to use the format directives for floating point printing to have the numbers always aligned in nice columns. You can choose between ~F that will never print an exponent, ~E that will always print one, and ~G that behaves according to the magnitude. Look for details here in the HyperSpec: http://www.lispworks.com/documentation/HyperSpec/Body/22_cc.htm.
Here's an example that uses ~F with a maximum field width of 5 and 1 fractional digit:
(dotimes (i 3)
(dotimes (j 3)
(format t "~5,1F" (get-real-2d a i j)))
(terpri))
This isn't hard, so I'd rather leave it to you to figure out, but here are some tips to make a "slick loop" Lisp-style. I would suggest one or more instances of mapc (or mapcar), rather than dotimes. This may feel odd if you're not used to functional programming, but once you're used to it, it's easier to read than dotimes, and you don't have to keep track of the indexes, so it can avoid errors. You really should learn to use mapcar/mapc if you aren't already familiar with them. They are cool. Or if you want to be really cool :-) you could use recursion to iterate over the matrix, but I think that for this purpose iterating using mapc will be easier to read. (But you should learn the recursive way for other jobs. If you find recursion confusing--I have no reason to think you do, but some people have trouble with it--my favorite tutorial is The Little Schemer.)
You may also want to use other format directives that allow you pad numbers with spaces if they don't have enough digits. The ~% directive may be useful as well. Peter Seibel has a very nice introduction to format.

BST printing without mutating?

So i basically want to printbst's .. here is a little more detail
Provide a function (printbst t) that prints a BST constructed from BST as provided by bst.rkt in the following format:
-Each node in the BST should be printed on a separate line;
-the left subtree should be printed after the root;
-The right subtree should be printed before the root;
-The key value should be indented by 2d spaces where d is its depth, or distance from the root. That is, the root should not be indented, the keys in its subtrees should be intended 2 spaces, the keys in their subtrees 4 spaces, and so on.
For example, the complete tree containing {1,2,3,4,5,6} would be printed like this:
6
5
4
3
2
1
Observe that if you rotate the output clockwise and connect each node to its subtrees, you arrive at the conventional graphical representation of the tree. Do not use mutation.
Here is what i have so far:
#lang racket
;;Note: struct-out exports all functions associated with the structure
(provide (struct-out BST))
(define-struct BST (key left right) #:transparent)
(define (depth key bst)
(cond
[(or (empty? bst) (= key (BST-key bst))) 0]
[else (+ 1 (depth key (BST-right bst)) (depth key (BST-left bst)))]))
(define (indent int)
(cond
[(= int 0) ""]
[else " " (indent (sub1 int))]))
(define (printbst t)
(cond
[(empty? t) (newline)]
[(and (empty? (BST-right t)) (empty? (BST-left t)))
(printf "~a~a" (indent (depth (BST-key t) t)) (BST-key t))]))
My printbst only prints a tree with one node thou .... i have an idea but it involves mutation, which i can't use :( ..... Any suggestions ? Should i change my approach to the problem all together?
Short answer: yes, you're going to want to restructure this more or less completely.
On the bright side, I like your indent function :)
The easiest way to write this problem involves making recursive calls on the subtrees. I hope I'm not giving away too much when I tell you that in order to print a subtree, there's one extra piece of information that you need.
...
Based on our discussion below, I'm going to first suggest that you develop the closely related recursive program that prints out the desired numbers with no indentation. So then the correct output would be:
6
5
4
3
2
1
Updating that program to the one that handles indentation is just a question of passing along a single extra piece of information.
P.S.: questions like this that produce output are almost impossible to write good test cases for, and consequently not great for homework. I hope for your sake that you have lots of other problems that don't involve output....

Find all possible pairs between the subsets of N sets with Erlang

I have a set S. It contains N subsets (which in turn contain some sub-subsets of various lengths):
1. [[a,b],[c,d],[*]]
2. [[c],[d],[e,f],[*]]
3. [[d,e],[f],[f,*]]
N. ...
I also have a list L of 'unique' elements that are contained in the set S:
a, b, c, d, e, f, *
I need to find all possible combinations between each sub-subset from each subset so, that each resulting combination has exactly one element from the list L, but any number of occurrences of the element [*] (it is a wildcard element).
So, the result of the needed function working with the above mentioned set S should be (not 100% accurate):
- [a,b],[c],[d,e],[f];
- [a,b],[c],[*],[d,e],[f];
- [a,b],[c],[d,e],[f],[*];
- [a,b],[c],[d,e],[f,*],[*];
So, basically I need an algorithm that does the following:
take a sub-subset from the subset 1,
add one more sub-subset from the subset 2 maintaining the list of 'unique' elements acquired so far (the check on the 'unique' list is skipped if the sub-subset contains the * element);
Repeat 2 until N is reached.
In other words, I need to generate all possible 'chains' (it is pairs, if N == 2, and triples if N==3), but each 'chain' should contain exactly one element from the list L except the wildcard element * that can occur many times in each generated chain.
I know how to do this with N == 2 (it is a simple pair generation), but I do not know how to enhance the algorithm to work with arbitrary values for N.
Maybe Stirling numbers of the second kind could help here, but I do not know how to apply them to get the desired result.
Note: The type of data structure to be used here is not important for me.
Note: This question has grown out from my previous similar question.
These are some pointers (not a complete code) that can take you to right direction probably:
I don't think you will need some advanced data structures here (make use of erlang list comprehensions). You must also explore erlang sets and lists module. Since you are dealing with sets and list of sub-sets, they seems like an ideal fit.
Here is how things with list comprehensions will get solved easily for you: [{X,Y} || X <- [[c],[d],[e,f]], Y <- [[a,b],[c,d]]]. Here i am simply generating a list of {X,Y} 2-tuples but for your use case you will have to put real logic here (including your star case)
Further note that with list comprehensions, you can use output of one generator as input of a later generator e.g. [{X,Y} || X1 <- [[c],[d],[e,f]], X <- X1, Y1 <- [[a,b],[c,d]], Y <- Y1].
Also for removing duplicates from a list of things L = ["a", "b", "a"]., you can anytime simply do sets:to_list(sets:from_list(L)).
With above tools you can easily generate all possible chains and also enforce your logic as these chains get generated.

Resources