Site Sponsors:
Microsoft Triumph! 
Some people say that we POSIX guys are biased. --Many believe that wee open source folks have something against commercial software platforms / tools.

In my case - as well as everyone else I know - nothing could be farther from the truth!

In very fact, while I personally do allot on free & open Linux / LAMP / POSIX worlds, when it comes to raking in the big bucks I - more often than not - find myself working with Microsoft technologies.

Indeed, we'll rake in ever more $$,$$$ when we combine POSIX, Microsoft, and other tools together (The higher the 'tech is stacked, the fewer there be to tackle it, my friends ...!)

Modern C/C++


While many marvelous tools have come and gone, at the time of this writing - and in my opinion - there are virtually NO decent open graphical tool sets for C/C++. --And I have tried just about all of them! (Conclusion: Never trust a developer - favoring ONE language - to concoct a language-savvy tooling ... for another?)

So as I turned my weary eyes back to Visual Studio this day, I was overjoyed to discover that "The Empire" has finally started to support those of us who - uh - like to live ... on "Hoth" ! (Cygwin and MinGW under Visual Studio? CLICK HERE!)


(Hey 'Darth: Say "CHEEESE?")

Indeed, after downloading Visual Studio's 2017 Community Edition so that I could play with libtcod (they no longer liked my '2013 Pro) I tell 'ya truly - that a relatively new editor - known as Visual Studio Code - works REAL WELL out of the box... even in our icy monster-caves:



Sure - when time for working on C# & VB comes again (as it always will!) I will surely upgrade the '2013 to VS 2017 -- or whatever else the emperor de-jure requires us to buy so as to continue to move our hostage-ware VS Projects (like libtcod!) forward in their empire.


In the mean time however, it is VERRRRY refreshing to be able to quickly do a 'git - edit - as well as work with the console tools directly from Visual Studio Code, Express, or the Community Editions!

Yet THAT - as we might say - and to complete the analogy - is merely the tip of this iceberg of what the entire VS Family-Empire can do for Modern C/C++! =)

(And yes Slytherin, the 'Empire now even supports Python!)

Want to learn more? Then here is how to "Use any C++ Compiler with Visual Studio"!


[ view entry ] ( 669 views )   |  permalink  |  related link
"Just Do It:" Graphical Command-Line Parameters for Python 3 
(UPDATED 2018-11-06: Code now available at GitHub)


There seems to be a huge line between those who want to use console applications, and those who have the need for a GUI.

When using Python however, such lines need not exist: It can be easy to jump between the the Graphical & Textual Worlds!


#!/usr/bin/python3
from tkinter import *

# Mission: Create a way to query a user for command-line values.
# Mission statement implies the encapsulation of a GUI paradigm.
# Here is how to do so using tkinter under Python 3.

''' Prompter: Graphically get a dictionary of command-line strings from a user.
Dictionary result is empty when the `cancel` button has been pressed, else the results
will contain the tag-value pairing (i.e. Dictionary keys match the fields requested, to
get the user's response for each field.)
'''
class Prompter:
def __init__(self):
self._dict = None
self._isOk = None
self.last_row = None

def _okay(self):
self._isOk = True
self.tk.quit()

def _cancel(self):
self._isOk = False
self.tk.quit()

@staticmethod
def Begin(*fields, title="Input"):
''' Create the frame, add the title, as well as the input fields.'''
from collections import OrderedDict
self = Prompter()
self.tk = Tk()

self._dict = OrderedDict()

if title:
self.tk.title(title)

self.last_row = 0
# zFields (A Label, plus an Entry, in a grid layout)
for ref in fields:
obj = Label(master=self.tk, text=str(ref))
obj.grid(row=self.last_row, column=0)

obj = Entry(master=self.tk, bd=5)
obj.grid(row=self.last_row, column=1)

self._dict[ref]=obj
self.last_row += 1
return self

@staticmethod
def End(prompter):
''' Add the closing buttons, center, and pack the Frame.'''
if prompter.last_row is None:
return False
if isinstance(prompter, Prompter) is False:
return False
# zButtons (A Frame in the grid, plus the properly-centered pair of buttons)
bottom = Frame(prompter.tk)
bottom.grid(row=prompter.last_row, columnspan=2)
btn = Button(bottom, text="Okay", command=prompter._okay)
btn.pack(side=LEFT, pady=12)

btn = Button(bottom, text="Cancel", command=prompter._cancel)
btn.pack(side=RIGHT, padx=10)

# zCenter (Close enough to make no odds?)
width = prompter.tk.winfo_screenwidth()
height = prompter.tk.winfo_screenheight()
x = (width - prompter.tk.winfo_reqwidth()) / 2
y = (height - prompter.tk.winfo_reqheight()) / 2
prompter.tk.geometry("+%d+%d" % (x, y))
return True

def show(self):
from collections import OrderedDict
self.tk.mainloop()
try:
results = OrderedDict()
if self._isOk is not True:
return results

for ref in self._dict.keys():
results[ref] = (self._dict[ref]).get()
return results
finally:
try:
self.tk.destroy()
except:
pass


@staticmethod
def Prompt(*fields, title="Input"):
''' Basic mission statement completed. '''
self = Prompter.Begin(*fields, title=title)
if Prompter.End(self) is False:
raise Exception("AddButtons: Unexpected Error.")
return self.show()


if __name__ == "__main__":
# Here is how we would use the Prompter from a Console Program:
results = Prompter.Prompt("this", "isa", "test", title="Just Do It!")
if len(results) is 0:
print("Pressed Cancel - no values!")
else:
print("Pressed Okay - got values!")
for ref in results:
print(ref, results[ref])


Taking time to review the test case, all one need do is to provide Prompter.InputStrings() with the queries. The title is optional.


Upon activation, Prompter.InputStrings() will create a reasonable-looking user interface, screen-center it & use it to query the user, then return a dictionary of the string response(s) provided.


When the user presses "cancel," the dictionary will be empty.

WIPI Results


Of course, one of the most annoying things about Dict()ionaries in this man's world is - at the time of this writing - the eccentric ordering of their key:value pairs.

Submitted for your perusal therefore, allow me to offer up Prompter.InputOrder() for your more predictable re-usages:

    @staticmethod
def InputOrder(*fields, title="Input"):
results = Prompter.InputStrings(*fields, title=title)
if len(results) is 0:
return [*zip([],[])]
data = []
for ref in fields:
data.append(results[ref])
results = zip(fields, data)
return [*results]

Designed to work exactly as Prompter.InputStrings() (sans the dict(), of course):


-Here be the test case:
    results = Prompter.InputOrder("this", "isa", "test", title="Just Do It!")
if len(results) is 0:
print("Pressed Cancel - no values!")
else:
print("Pressed Okay - got values!")
for ref in results:
print(ref[0], ref[1])
-With the much more predictable, everything is WHERE-I-PUT-IT (W.I.P.I = 'wippy') 'list of lists' result paring:



[ view entry ] ( 918 views )   |  permalink  |  related link
Tagging Your MP# Files 
Command-line audiophiles of all descriptions surely know about ffmpeg - The de-facto way of managing allot more than MP3 files, ffmpeg ranks highly - even amongst the audacity set - for managing the ear-candy.



An avid consumer of every audio book I can afford (I get about 2 a year - Christmas & Father's day :) once ripped from the CDs most book-listeners feel that any random-play feature - as enjoyed by most of the planet - should be considered a form of torture.

Until so considered by a joint Geneva / UN-declaration, like many we simply *need* to combine all spoken-word tracks into a SINGLE album-file, or risk going 'radical ;-)

Tweakin' Tags


When it comes time to update the tags for our audio amalgamations, rather than using ffmpeg however, one will find the services of the taglib examples to be in high-demand. Namely, `tagreader` and `tagwriter`.

Designed to do precisely what their names imply, one can save hours by updating music meta-data in place.

Indeed, with a collection of over 60 unifile audiobooks to update, commands such as:

ffmpeg -i /MyMedia/AudioBooks/SW_05_02_21_The_Unifying_Force.mp3 -metadata title="SW_05_02_21_The_Unifying_Force" /MyMedia/biglist/SW_05_02_21_The_Unifying_Force.mp3
on a 1.2 GB file ... are simply evil!

The Recipe


Unlike using ffmpeg (sudo-installable,) using taglib's examples are - at the time of this telling - never for the faint-hearted.

For those who would like to use the aforementioned pair of tag-management console tools however, here are my notes:

# (1) You must install Gnu's C/C++
sudo apt-get install c++

# (2) You must install CMake
sudo apt-get install cmake

# (3) You mist install BOOST
sudo apt-get install libboost-all-dev

# (4) You must download, unpack, make & install taglib
cd /<wherever_unziped>/taglib-1.11.1
cmake -DBUILD_EXAMPLES=ON -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release .
make
sudo make install

# (5) The examples folder under <wherever_unziped> will have the tagreader & tagwriter
-rwxr-xr-x 1 root root 1281440 Feb 24 04:31 tagreader
-rwxr-xr-x 1 root root 1287144 Feb 24 04:31 tagreader_c
-rw-rw-r-- 1 root root 2913 Oct 23 23:03 tagreader_c.c
-rw-rw-r-- 1 root root 3413 Oct 23 23:03 tagreader.cpp
-rwxr-xr-x 1 root root 1282016 Feb 24 04:31 tagwriter
-rw-rw-r-- 1 root root 5201 Oct 23 23:03 tagwriter.cpp


Caveat Python


Note: For those who would like to use `pip install pytaglib` under Python / PyPi, note that we came up with the above strategy rather than swimming thru the plethora of build problems. (*)

Not only will one need to install taglib anywize, but by simply building the examples (-DBUILD_EXAMPLES=ON, above) you'll already have what you need to manage your audio metadata without writing a single line of code:
./tagwriter

Usage: tagwriter <fields> <files>

Where the valid fields are:
-t <title>
-a <artist>
-A <album>
-c <comment>
-g <genre>
-y <year>
-T <track>
-R <tagname> <tagvalue>
-I <tagname> <tagvalue>
-D <tagname>
And yes, FWIW the taglib heroes have my personal vote for surely what be the all-time best `example` program in the history of example-program-oscpacy. -Right down to that macho, got-my big-boy pants-on, C++ incarnation. ;-)


(*) Example of the `pip3 install pytaglib` woes:
fatal error: taglib/tstring.h: No such file or directory
is just the beginning of the problem - after getting past those, one will also see errors such as:
/usr/bin/ld: //usr/local/lib/libtag.a(tstring.cpp.o): relocation R_X86_64_32S against `_ZTVN6TagLib6StringE' can not be used when making a shared object; recompile with -fPIC
Is not life too short for thousands of developers to be fixing that type of nonsense ... in a PyPi Package?


[ view entry ] ( 908 views )   |  permalink  |  related link

<<First | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Next> Last>>