reading MIDI file using music21 with partitionByInstrument() to get notes and chords returning empty list - midi

I'm trying to use the code from this github repository's .py file (the get_notes() function) to extract the notes and chords data from this midi file. Here is the exact code copied from the repo I'm using:
def get_notes():
""" Get all the notes and chords from the midi files in the ./midi_songs directory """
notes = []
for file in glob.glob("midi_songs/*.mid"):
midi = converter.parse(file)
print("Parsing %s" % file)
notes_to_parse = None
try: # file has instrument parts
s2 = instrument.partitionByInstrument(midi)
notes_to_parse = s2.parts[0].recurse()
except: # file has notes in a flat structure
notes_to_parse = midi.flat.notes
for element in notes_to_parse:
if isinstance(element, note.Note):
notes.append(str(element.pitch))
elif isinstance(element, chord.Chord):
notes.append('.'.join(str(n) for n in element.normalOrder))
with open('data/notes', 'wb') as filepath:
pickle.dump(notes, filepath)
return notes
My midi file has multiple instruments, which I believe for some reason is causing nothing to be appended to the notes list. Seeing as I've just cloned the repository's code and run it on my own midi file, I'm not sure why it isn't working. I've looked through the documentation for music21's partitionByInstrument(), and tried to iterate through the different instruments by changing:
notes_to_parse = s2.parts[0].recurse()
to
notes_to_parse = s2.parts[1].recurse()
as different parts should be different instruments from the file, but it still returns an empty list. What do I do?

v6.1 added a feature to create Instrument objects from MIDI instrument name and track name messages. v6.5, which came out today, added a feature to remove duplicates caused when there is also an Instrument from a program change message at the same tick. If you try out v6.5 you may find this to be easier to use.

It was simply the fact that it was taking the first instrument it found, which had no data for notes, durations or offsets. Iterating through the instruments I got different ones returning full lists.

Related

Migrating from itext2 to itext7

Years ago, I wrote a small app in itext2 to gather reports on a weekly basis and concatenate them into one PDF. The app used com.lowagie.text.pdf.PdfCopy to copy and merge the PDFs. And it worked fine. Performed exactly as expected.
A few weeks ago I looked into migrating the application to itex7. To that end, I used the copyPagesTo method of com.itextpdf.kernel.pdf.PdfDocument. When run on the same file set, this produces warnings like:
WARN PdfNameTree - Name "section.1" already exists in the name tree; old value will be replaced by the new one.
When I click on the link to "section.1" in the first document of the merged PDF, I am taken to "section.1" of the last document. Not what I expected and not what happens when using the itext2 app. In the PDF's produced by itext2, if I click on the link to "section.1" of the first document in the combined PDF, I am taken to section 1 of the first document.
There is a hint in Javadocs for copyPagesTo saying
If outlines destination names are the same in different documents, all
such outlines will lead to a single location in the resultant
document. In this case iText will log a warning. This can be avoided
by renaming destinations names in the source document.
There is however, no explanation of how this should be done. I find it odd that this should be necessary in itext7, although it wasn't in itext2.
Is there a simple way to get around his problem?
I've also tried the Sejda desktop app and it produces correct results, but I would prefer to automate the process through a batch script.
My guess is iText 2 didn't even know it might be a problem.
If iText can't deduplicate destination names, the procedure is roughly:
Follow /Catalog -> /Names -> /Dests in each document to find the destination name tree.
Deduplicate the names, by adding suffixes. Remember that a name with a suffix added might be equal to an existing name in the same or another document. Be careful!
Now you can rewrite the destination name trees. Since you have only used suffixes, you can do this in place - the lexicographic ordering of the names is unaltered so the search tree structure is not broken.
Now, rewrite destination links in each PDF for the new names. For example any dictionary entry with key /Dest, or any /D in a /GoTo action.
Now, after all this preprocessing, the files will merge without name clashes.
(I know all this because I've just implemented it for my own PDF software. It's slightly hairy stuff, but not intractable.)
If you like, I can provide a devel version of cpdf with this functionality, if you would like to test it.

How can I manually edit the list of recently opened files in VS Code?

I rely heavily on the File: Open Recent… command to open frequently used files, but yesterday my local Google Drive folder got moved to a new location and now I can no longer access any of the files in that folder through the Open Recent panel because the paths don't match.
The fix would be as simple as replacing "/Google Drive/" with "/Google Drive/My Drive/" but I have no idea what file contains the list of files that appears in the recently opened panel.
I'm assuming it's somewhere in ~/Library/Application Support/Code but not sure where.
I was wondering the same thing the other day and found this while searching for a solution, so I took some time to investigate it today.
It's been a a few weeks since you posted, so hopefully this will still be of help to you.
Also, I'm using Windows and I'm not familiar with macOS, but I think it should be easy enough adjust the solution.
Location of settings
Those setting are stored in the following file: %APPDATA%\Code\User\globalStorage\state.vscdb.
The file is an sqlite3 database, which is used as a key-value store.
It has a single table named ItemTable and the relevant key is history.recentlyOpenedPathsList.
The value has the following structure:
{
"entries": [
{
"folderUri": "/path/to/folder",
"label": "...",
"remoteAuthority": "..."
}
]
}
To view the current list, you can run the following command:
sqlite3.exe -readonly "%APPDATA%\Code\User\globalStorage\state.vscdb" "SELECT [value] FROM ItemTable WHERE [key] = 'history.recentlyOpenedPathsList'" | jq ".entries[].label"
Modifying the settings
Specifically, I was interested in changing the way it's displayed (the label), so I'll detail how I did that, but it should be just as easy to update the path.
Here's the Python code I used to make those edits:
import json, sqlite3
# open the db, get the value and parse it
db = sqlite3.connect('C:/Users/<username>/AppData/Roaming/Code/User/globalStorage/state.vscdb')
history_raw = db.execute("SELECT [value] FROM ItemTable WHERE [key] = 'history.recentlyOpenedPathsList'").fetchone()[0]
history = json.loads(history_raw)
# make the changes you'd like
# ...
# stringify and update
history_raw = json.dumps(history)
db.execute(f"UPDATE ItemTable SET [value] = '{history_raw}' WHERE key = 'history.recentlyOpenedPathsList'")
db.commit()
db.close()
Code references
For reference (mostly for my future self), here are the relevant source code areas.
The settings are read here.
The File->Open Recent uses those values as-is (see here).
However when using the Get Started page, the Recents area is populated here. In the Get Started, the label is presented in a slightly different way:
vscode snapshot
The folder name is the link, and the parent folder is the the text beside it.
This is done by the splitName method.
Notes
Before messing around with the settings file, it would be wise to back it up.
I'm not sure how vscode handles and caches the settings, so I think it's best to close all vscode instances before making any changes.
I haven't played around with it too much, so not sure how characters that need to be json-encoded or html-encoded will play out.
Keep in mind that there might be some state saved by other extensions, so if anything weird happens, blame it on that.
For reference, I'm using vscode 1.74.2.
Links
SQLite command-line tools
jq - command-line JSON processor

Automatically download emails from Outlook with SAS or Outlook rule

I am trying to create a program to automatically download the attached files that are sent to us from a certain email and then transform the delimiter with SAS, of those csv that are attached to us and pass those csv through a flow that I have already created.
I have managed to create a program that treats the csv as I want and the delimiter that I want, the problem is that when it comes to automating the download of files from Outlook it does not work.
What I have done is create a rule with the following VB code that I found on the internet:
Public Sub SaveAttachmentsToDisk(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
sSaveFolder = "C:\Users\ES010246\Desktop"
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
Next
End Sub
I have changed the path to my personal path where i want the files are downloaded.
website: https://es.extendoffice.com/documents/outlook/3747-outlook
The problem is that this code does not work for me, it does absolutely nothing for me and no matter how much I search the internet, only this code appears.
Is there any other way to do with SAS what I want? What is it to automatically download 8 csv files sent to me by Outlook, or has someone experienced the same thing as me with VBA?
I have followed all the steps about 7 times so I think the error is not in copying the code or selecting certain options wrong, in fact I had copied and pasted the code and later I modified the path where I wanted those to be saved. files but it doesn't work, does anyone know why?
I will be tremendously grateful, thank you very much for everything!
First of all, you need to make sure the file name and path doesn't include forbidden symbols.
The VBA macro used for a rule in Outlook is absolutely valid except that a mail item may contain the attached files with the same name, so a file saved to the disk may be overwritten (saved with the same name). That's why I'd suggest generating a file name with your own unique IDs making sure that DisplayName property is not empty and has a valid name what can be used for file names (exclude forbidden symbols).
Also you may consider handling the NewMailEx event of the Application class which is fired when a new message arrives in the Inbox and before client rule processing occurs. Use the Entry ID returned in the EntryIDCollection string to call the NameSpace.GetItemFromID method and process the item. This event fires once for every received item that is processed by Microsoft Outlook. The item can be one of several different item types, for example, MailItem, MeetingItem, or SharingItem.
The Items.ItemAdd event can be helpful when items are moved to a folder (from Inbox). This event does not run when a large number of items are added to the folder at once.

Searching all file names recursively in hdfs using Spark

I’ve been looking for a while now for a way to get all filenames in a directory and its sub-directories in Hadoop file system (hdfs).
I found out I can use these commands to get it :
sc.hadoopConfiguration.set("mapreduce.input.fileinputformat.input.dir.recursive", "true")
sc.wholeTextFiles(path).map(_._1)
Here is "wholeTextFiles" documentation:
Read a directory of text files from HDFS, a local file system (available on all nodes), or any Hadoop-supported file system URI. Each file is read as a single record and returned in a key-value pair, where the key is the path of each file, the value is the content of each file.
Parameters:
path - Directory to the input data files, the path can be
comma separated paths as the list of inputs.
minPartitions - A
suggestion value of the minimal splitting number for input data.
Returns:
RDD representing tuples of file path and the corresponding
file content
Note: Small files are preferred, large file is also
allowable, but may cause bad performance., On some filesystems,
.../path/* can be a more efficient way to read all files in a
directory rather than .../path/ or .../path, Partitioning is
determined by data locality. This may result in too few partitions by
default.
As you can see "wholeTextFiles" returns a pair RDD with both the filenames and their content. So I tried mapping it and taking only the file names, but I suspect it still reads the files.
The reason I suspect so: if I try to count (for example) and I get the spark equivalent of "out of memory" (losing executors and not being able to complete the tasks).
I would rather use Spark to achieve this goal the fastest way possible, however, if there are other ways with a reasonable performance I would be happy to give them a try.
EDIT:
To clear it - I want to do it using Spark, I know I can do it using HDFS commands and such thing - I would like to know how to do such thing with the existing tools provided with Spark and maybe an explanation on how I can make "wholeTextFiles" not reading the text itself (kind of like how transformations only happen after an action and some of the "commands" never really happen).
Thank you very much!
This is the way to list out all the files till the depth of last subdirectory....and is with out using wholetextfiles
and is recursive call till the depth of subdirectories...
val lb = new scala.collection.mutable[String] // variable to hold final list of files
def getAllFiles(path:String, sc: SparkContext):scala.collection.mutable.ListBuffer[String] = {
val conf = sc.hadoopConfiguration
val fs = FileSystem.get(conf)
val files: RemoteIterator[LocatedFileStatus] = fs.listLocatedStatus(new Path(path))
while(files.hasNext) {// if subdirectories exist then has next is true
var filepath = files.next.getPath.toString
//println(filepath)
lb += (filepath)
getAllFiles(filepath, sc) // recursive call
}
println(lb)
lb
}
Thats it. it was tested with success. you can use as is..

Open .mat file in matlab or unix - new user

I am going through someone's data analysis files (created in an older version of matlab) and trying to find out what a particular .mat file is that was used in a matlab script.
I am trying to load a .mat file in matlab. I want to see what is in it.
When I type...
load ('file.mat')
the file loads and I see two variables appear in the workspace. jobhelp and jobs.
When I try to open jobs by typing the following in the matlab command window...
jobs
the response is..
jobs =
[1x1 struct]
Does this mean that there is only a 1 x 1 structure in the .mat file? If so, how in the world do I see what it is? I'm even happy to load it in unix, but I don't know how to do that either. Any help would be greatly appreciated as I have a few files like this that I can't get any information from.
Again, a new user, so please make it simple.
Thanks
It means that jobs is a cell array {} and within this cell array is a structure defined
To see the structure and its contents type jobs{1}
I think you are dealing with a SPM5 Batch-File. This variable is an image of the tree-like structure you can see in the Batch-Editor of SPM. Your job consists of one subitem (stats) which could have various subsubitems (like fMRI model specification, model estimation and so on).
To access this structure on the command line just proceed like Nick said:
Each level is a separate cell array that you can access with {#} after the name of the level. Example: jobs{1} shows you that there is a subitem named stats.
Subitems in structs are accessed with a dot. Example: jobes{1}.stats{1} shows you the subitems of the stats-entry.
Notice that there could be more than one entry on each layer: A stats module could (and probably would) contain various subitems. You can access them via jobs{1}.stat{2}, jobs{1}.stats{3} and so on.
The last layer would be the interesting one for you: The structures in here is an image of the options you can choose in the batch-editor.