Wednesday, December 2, 2015

Friday, October 2, 2015

Building a Plex Plugin from scratch

First of all, some important url-s for learning:
 Seconds, the skeleton  (directories and files) of a plex plugin (all are case sensitive):
  • MyPlugin.bundle
    • Contents
      • Code
        • __init__.py
      • Info.plist
An absolute minimal content of the Info.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>CFBundleIdentifier</key>
 <string>com.plexapp.plugins.myplugin</string>
 <key>PlexFrameworkVersion</key>
 <string>2</string>
 <key>PlexClientPlatforms</key>
 <string>*</string>
</dict>
</plist>
An absolute minimal content of the __init__.py (for a responding plugin):
@handler('/video/myplugin', 'My Plugin')
def Main(): # this is the landing page of the plugin because of the prefix handler.
    return ObjectContainer()
That's it. Every plugin grows out from this root :)

Okay, one thought to developing a plex plugin: without a proper IDE, you're dooooomed! :D Okay, maybe not, but if you use other people's code than sorting out python syntax errors (like: there's a tab instead of space, and here's a comma missing, thet indentation is only 2 space not 4, etc) can be quite annoying since the Plex server does not help much with debugging (it either responds or not, but that's it).
Anyway, I managed to make my first plex plugin work... or at least some parts of it, and at least on my PC :) Here it is.


This post was originally published on my other blog, Alice@Ubuntu, but considering the content, I moved it here.

Monday, May 25, 2015

Notes on Python for Informatics Chapter 4: Functions

Source

Function calls

function: A named sequence of statements that performs some useful operation. Functions may or may not take arguments and may or may not produce a result.
function call: A statement that executes a function. It consists of the function name followed by an argument list.
argument: A value provided to a function when the function is called. This value is assigned to the corresponding parameter in the function.
return value: The result of a function. If a function call is used as an expression, the return value is the value of the expression.

Built-in functions
Python provides a number of important built-in functions that we can use without needing to provide the function definition. 
Some of these we already used:
type() # With one argument, return the type of an object.
raw_input()  #  Reads a line from input, converts it to a string, and returns that.
Type conversion functions
float() # Return a floating point number constructed from a number or string x.
int() # Return an integer object constructed from a number or string x.
str() # Return a string containing a nicely printable representation of an object.
...and some will come handy later:
len() # Return the length (the number of items) of an object
min() # Return the smallest item in an iterable or the smallest of two or more arguments.
max() # Return the largest item in an iterable or the largest of two or more arguments.

dir() # Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object.
help() # the built-in help system. (This function is intended for interactive use.) If no argument is given, the interactive help system starts on the interpreter console. If the argument is a string, then the string is looked up as the name of a module, function, class, method, keyword, or documentation topic, and a help page is printed on the console. If the argument is any other kind of object, a help page on the object is generated.

list() # Returns a list object
dict() # Returns a dictionary object
tuple() # Returns a tuple object
set()  # Returns a new set object
open()  # Open a file, returning an object of the file type
range()  # This is a versatile function to create lists containing arithmetic progressions. It is most often used in for loops.

Modules
Modules are external containers of pre-written and reusable functions and variables. Python comes with a library of standard modules, described in a separate document, the Python Library Reference (“Library Reference” hereafter).
To import a module, type import and the module name, like:
import random
This statement creates a module object named random.
To access one of the functions, you have to specify the name of the module and the name of the function, separated by a dot (also known as a period). This format is called dot notation.
import statement: A statement that reads a module file and creates a module object.
module object: A value created by an import statement that provides access to the data and code defined in a module. 
dot notation: The syntax for calling a function in another module by specifying the module name followed by a dot (period) and the function name.

Random numbers
algorithm: A general process for solving a category of problems.
deterministic: Pertaining to a program that does the same thing each time it runs, given the same inputs.
Making a program truly nondeterministic turns out to be not so easy, but there are ways to make it at least seem nondeterministic.
pseudorandom: Pertaining to a sequence of numbers that appear to be random, but are generated by a deterministic program.

The Random module is a Python standard module. The functions in it can be used to generate pseudorandom numbers. Some example functions are:
random.random() # Return the next random floating point number in the range [0.0, 1.0].
random.randint(a, b) # Return a random integer N such that a <= N <= b.
random.choice(seq) # Return a random element from the non-empty sequence seq.
Math functions
example functions from the math module

Adding new functions

Once we define a function, we can reuse the function over and over throughout our program.
function object: A value created by a function definition. The name of the function is a variable that refers to a function object. 
Definitions and uses
The function definition is also a compound statement, therefore it has a header and a body.
function definition: A statement that creates a new function, specifying its name, parameters, and the statements it executes.
Flow of execution
Functions have to be defined in the flow of execution before their first use.
When function definition code runs, only the function object is created, but the code inside it does not run until it is called.
flow of execution: The order in which statements are executed during a program run.

Parameters and arguments
As we have seen, some of the built-in functions require arguments. Inside the function, the arguments are assigned to variables called parameters.
def print_twice(arg):
    print arg
    print arg
parameter: A name used inside a function to refer to the value passed as an argument.
composition: Using an expression as part of a larger expression, or a statement as part of a larger statement.

Fruitful functions and void functions
For lack of a better name, the functions that yield result are called here fruitful functions. In comparison to the functions that don't return a value, which are called here void functions.
fruitful function: A function that returns a value.
When you call a fruitful function, you almost always want to do something with the result; for example, you might assign it to a variable or use it as part of an expression. 
def list_twice(arg):
    twice = [arg, arg]
    return twice 
void function: A function that doesn’t return a value.
When you try to assign a void function to a variable, the value that will get assigned is the special value None.
def print_twice(arg):
    print arg
    print arg

Why functions?
There are several reasons why it is worth the trouble to divide a program into functions:
  • Creating a new function gives you an opportunity to name a group of statements, which makes your program easier to read, understand and debug.
  • Functions can make a program smaller by eliminating repetitive code. Later, if you make a change, you only have to make it in one place.
  • Dividing a long program into functions allows you to debug the parts one at a time and then assemble them into a working whole.
  • Well-designed functions are often useful for many programs. Once you write and debug one, you can reuse it.
Throughout the rest of the book, often we will use a function definition to explain a concept. Part of the skill of creating and using functions is to have a function properly capture an idea such as “find the smallest value in a list of values”. This idea is captured by the function named min which takes a list of values as its argument and returns the smallest value in the list.

Notes on Python for Informatics Chapter 5: Iteration

Source

Updating variables

A common pattern in assignment statements is an assignment statement that updates a variable - where the new value of the variable depends on the old.
Before you can update a variable, you have to initialize it.

initialize: An assignment that gives an initial value to a variable that will be updated.
x = 0 # is equivalent to x = int()
x = 0.0 # is equivalent to x = float()
y = '' # is equivalent to x = str()
# the following are still not discussed types:
a = [] # is an empty list, and equivalent to a = list()
b = {} # is an empty dictionary, and equivalent to b = dict()
c = () # is an empty tuple, and equivalent to c = tuple()
Updating a variable by adding 1 is called an increment; subtracting 1 is called a decrement. decrement: An update that decreases the value of a variable.
increment: An update that increases the value of a variable (often by one).
x = x + 1 # is an incrementation and equivalent to x += 1
x = x - 1 # is a decrementation and equivalent to x -= 1

Loops and Iterations

Loops are used for repeating identical or similar tasks. Each time we execute the body of the loop (it has a header and a body, because it is a compound statement), we call it an iteration. We can say, “This loop had n iterations” which means that the body of the loop was executed n times.
iteration: Repeated execution of a set of statements using either a recursive function call or a loop.
iteration variable: The variable that is tested in the loop header condition for being True, every time the loop executes and therefore controls when the loop finishes.

The while statement
The while statement is used for repeated execution as long as an expression is true. 
The header of the statement has the conditional expression, which is repeatedly tested, while it yields True.

The flow of execution for a while statement:
  1. Evaluate the condition, yielding True or False.
  2. If the condition is True, execute the first suite of the body and then go back to step 1. 
  3. If the condition is False, and a second suite of the else clause is present, it is executed, and and the loop terminates.
In case of the while statement, the body of the loop should change the iteration variable, so that eventually the condition becomes false and the loop terminates.

Infinite loops 
infinite loop: A loop in which the terminating condition is never satisfied or for which there is no termination condition.
while True:
    print "This loop will never terminate" 
“Infinite loops” and break; and Finishing iterations with continue
The break statement breaks out of the smallest enclosing loop.
The continue statement continues with the next iteration of the loop.
This way, the "while True" loop can be controlled from within:

while True:
    line = raw_input('> ')
    if line[0] == '#' :
        continue
    if line == 'done':
        break
    print line

Definite loops using for 
When we have a list of things to loop through, we can construct a definite loop using a for statement. We call the while statement an indefinite loop because it simply loops until some condition becomes False whereas the for loop is looping through a known set of items so it runs through as many iterations as there are items in the set.
Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence.
The break and continue statements can be used with the for loop too.
Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement
A quick way to make a sequence to iterate through with the for loop is by using the built-in function range().

Loop patterns
These loops (while & for) are generally constructed by:
  • Initializing one or more variables before the loop starts.
  • Performing some computation on each item in the loop body, possibly changing the variables in the body of the loop.
  • Looking at the resulting variables when the loop completes.
Counting and summing loops
Loops are often used for counting and accumulating elements.
accumulator: A variable used in a loop to add up or accumulate a result.
counter: A variable used in a loop to count the number of times something happened. We initialize a counter to zero and then increment the counter each time we want to “count” something. 

Wednesday, February 18, 2015

Replacing Bash with Python?

Since I'm very new to Python, but already familiar with Bash, I asked google search if it is a good idea to use Python instead of Bash.

It seems that generally Bash can be replaced with Python, integrating Bash and Python functionality. It is generally said that programming in Python is easier and more convenient than programming in Bash.
However, there are cases when it is rationally recommended to stick with Bash instead of Python:
"I agree that bash's syntax is pretty awful except for the one thing it does very well, which is execute programs (and pipe their output into other programs). Its syntax is very optimized for that. And yes, implementing find(1) yourself in Python is more work than just using find directly. :)"
When migrating from Bash to Python while still learning Python, it is recommended to do it slowly, taking one step at a time, replacing only those pieces in your bash script, that are easier to do in Python than in Bash:
  1. Replace AWK and PERL with Python. Leave everything else alone.
  2. Look at replacing GREP with Python. This can be a bit more complex, but your version of GREP can be tailored to your processing needs.
  3. Look at replacing FIND with Python loops that use os.walk. This is a big win because you don't spawn as many processes.
  4. Look at replacing common shell logic (loops, decisions, etc.) with Python scripts.
RedHat Magazine has an enjoyable article by Noah Gift about working your way through the learning process. When reading it, the whole migration seems so easy...

It is also a good idea to get familiar with some Python modules that can help in replacing Bash with Python:
  • subprocess - an implemented module
  • sh - a non implemented module
  • plumbum - a library for shell script-like programs in Python

There is also an interactive Python shell that might replace the linux shell for you:

Tuesday, February 17, 2015

Notes on Python for Informatics Chapter 3: Conditional execution

Source

What is Conditional execution?

Conditional execution is a building block of programs. A condition determines if a part of the program will run at all.
  • conditional statement: A statement that controls the flow of execution depending on some condition.
  • condition: The boolean expression in a conditional statement that determines which branch is executed.
    • boolean expression: An expression whose value is either True or False.
    • branch: One of the alternative sequences of statements in a conditional statement. 

Types of conditional execution

The most simple conditional statement has only one branch:

if x > 0:
    print 'x is positive'
More complex versions are:
  • alternative execution: A conditional statement with two alternative branches.
if x%2 == 0 :
    print 'x is even'
else :
    print 'x is odd'
  • chained conditional: A conditional statement with a series of alternative branches. 
if x < y:
    print 'x is less than y'
elif x > y:
    print 'x is greater than y'
else:
    print 'x and y are equal'
  • nested conditional: A conditional statement that appears in one of the branches of another conditional statement. 
if x == y:
    print 'x and y are equal'
else:
    if x < y:
        print 'x is less than y'
    else:
        print 'x is greater than y'

What type of Conditions can be used?

  • comparison operator: One of the operators that compares its operands:
    • <        # strictly less than
    • <=      # less than or equal
    • >        # strictly greater than
    • >=      # greater than or equal
    • ==      # equal
    • !=       # not equal. (<> was used in old version)
  • logical operator: One of the operators that combines boolean expressions:
    •  x or y      # if x is false, then y, else x
      • This is a short-circuit operator, so it only evaluates the second argument if the first one is False.
    • x and y     # if x is false, then x, else y
      • This is a short-circuit operator, so it only evaluates the second argument if the first one is True.
    • not x    # if x is false, then True, else False
      • not has a lower priority than non-Boolean operators, so not a == b is interpreted as not (a == b), and a == not b is a syntax error.
    • short circuit: When Python is part-way through evaluating a logical expression and stops the evaluation because Python knows the final value for the expression without needing to evaluate the rest of the expression.
    • guardian pattern: Where we construct a logical expression with additional comparisons to take advantage of the short circuit behavior. 
      • i.e. if we want to avoid zero division, we could put a !=0 condition on the divisor.

Compound Statements 

  • compound statement: A statement that consists of a header and a body. The header ends with a colon (:). The body is indented relative to the header.
  • body: The sequence of statements within a compound statement.
Examples:
  • if statement is used for conditional execution
  • while statement is used for repeated execution
  • for statement is used for repeated execution
  • try statement is used forexception handling
Syntax:
  • Indenting and dedenting is a grammar rule of Python. 
  • A compound statement's body is always indented relative to the header. 
  • To set the end of the body, the code should be dedented. 
  • When indenting, whitespace should be used consequently: it is required to use only one type of whitespace within a single code file (4 spaces or one tab for one level of indentation).

Handling (catching) exceptions

It is possible to resolve foreseen errors with the try statement.
Unresolved errors make the program quit with a traceback massage (if it was run from a script file).
  • traceback: A list of the functions that are executing, printed when an exception occurs. 
inp = raw_input('Enter Fahrenheit Temperature:')
try:
    fahr = float(inp)
    cel = (fahr - 32.0) * 5.0 / 9.0
    print cel
except:
    print 'Please enter a number'

Reserving space in code structure for later usage

It is possible to leave parts of code to be written later by reserving the space in the code structure with the pass statement:
if x < 0 : 
    pass # need to handle negative values!

Notes on Python for Informatics Chapter 2: Variables, expressions and statements

Source

There are different value types. 

  • type: A category of values. The types we have seen so far are integers (type int), floating-point numbers (type float), and strings (type str).
  • value: One of the basic units of data, like a number or string, that a program manipulates.
The type of a value can be retrieved with the type() built-in function.
Examples:
  • int - integer number i.e. 1, 2
  • float - floating point number i.e. 1.0, 1.187694652
  • str - string text i.e. "1", "Hello World!"
  • bool - boolean (either true or false) i.e. True, False (note the case!)
Explanation:
  • string: A type that represents sequences of characters.
  • integer: A type that represents whole numbers.
  • floating-point: A type that represents numbers with fractional parts.
Read more on Python's Built-in Types 
Read more on Python's Built-in Functions

Variables represent values.

  • variable: A name that refers to a value.
  • assignment: A statement that assigns a value to a variable.
Examples:
  • x = 1
  • x = 1.0
  • x = "one"
  • x = True
It is generally a good idea to use mnemonic variable names that refer to the content of the variable.
  • mnemonic: A memory aid. We often give variables mnemonic names to help us remember what is stored in the variable.
Rules regarding variable names:
  • They have to begin with a letter (exception: variable names can start with an underscore character but this for is generally used for library code.)
  • They can contain letters (both upper and lowercase) and numbers and the underscore character (_)
  • They are case sensitive (it is suggested to use only lowercase letters in variable names) - just like everything else in Python
  • They can be arbitrarily long
The reserved words (keywords) of Python cannot be assigned as variable names.
  • keyword: A reserved word that is used by the compiler to parse a program.
Read the full list of Python's keywords

Comments can be made on the program code.

  • comment: Information in a program that is meant for other programmers (or anyone reading the source code) and has no effect on the execution of the program.
A comment starts with the # character, and lasts until the end of the line.
Examples:
  • # This whole line is a comment
  • x = 1 # The part before the "#" will run as a code, but the rest is a comment.

Statements

  • statement: A section of code that represents a command or action.
Examples:
  • x = 3.5 # assignment statement
  • print x # print statement

Operators and Operands

  • operator: A special symbol that represents a simple computation like addition, multiplication, or string concatenation. 
  • operand: One of the values on which an operator operates.
Different operations can be run on differen types of values.
Examples of numeric type operators:
  • + performs addition
  • - performs subtraction
  • * performs multiplication
  • / performs division (always in Python 3) or floor division depending on the value type (in Python 2)
  • // performs always floor division
  • % performs division and results the remainder of the division
  • ** performs exponentiation
Explanation:
  • floor division: The operation that divides two numbers and chops off the fraction part.
  • modulus operator: An operator, denoted with a percent sign (%), that works on integers and yields the remainder when one number is divided by another.
Examples of sequence type operators:
  • + performs concatenation
  • concatenate: To join two operands end-to-end.  I.e. "2" + "3" concatenates to "23"
Read more on numeric types and their operators.
Read more on sequence types and their operators.

Expressions

  • expression: A combination of variables, operators, and values that represents a single result value. 
Examples:
  • x # if x already has a value assigned
  • x + 1 # if x already has a value assigned
  • 1
  • 20 + 32 * (x - 1) / (x * 60 ) + x * x / 60 * 5**2 - ( 5 + 9 ) * ( 15 - 7 )
  • evaluate: To simplify an expression by performing the operations in order to yield a single value.
Examples, taken that x = 5
  • x # will yield 5
  • x + 1 # will yield 6
  • 1 # will yield 1
  • 20 + 32 * (x - 1) / (x * 60 ) + x * x / 60 * 5**2 - ( 5 + 9 ) * ( 15 - 7 ) # will yield -92 because of the rules of precedence.
  • rules of precedence: The set of rules governing the order in which expressions involving multiple operators and operands are evaluated.
For mathematical operators, Python follows mathematical convention. The acronym PEMDAS is a useful way to remember the rules:
  • Parentheses have the highest precedence and can be used to force an expression to evaluate in the order you want. Since expressions in parentheses are evaluated first, 2 * (3-1) is 4, and (1+1)**(5-2) is 8. You can also use parentheses to make an expression easier to read, as in (minute * 100) / 60, even if it doesn’t change the result.
  • Exponentiation has the next highest precedence, so 2**1+1 is 3, not 4, and 3*1**3 is 3, not 27.
  • Multiplication and Division have the same precedence, which is higher than Addition and Subtraction, which also have the same precedence. So 2*3-1 is 5, not 4, and 6+4/2 is 8, not 5.
  • Operators with the same precedence are evaluated from left to right. So in the expression 5-3-1 is 1, not 3 because the 5-3 happens first and then 1 is subtracted from 2.

User input

The user can be prompted to input data through the keyboard with the raw_input() built-in function.

Sunday, February 8, 2015

Reserved words of Bash

Source

!         case      esac      in        while
[[        do        fi        select   
]]        done      for       then   
{         elif      function  time   
}         else      if        until  
 

Friday, February 6, 2015

Reserved words of Python


and del from not while as elif global or with assert else if pass yield break except import print class exec in raise continue finally is return def for lambda try

Notes on Python for Informatics Chapter 1: Why should you learn to write programs?

Source

What does a programmer do:

  • knows a programming language (i.e. Python) - "words", "sentences", "paragraphs", etc.
  • "tells a story": combine the text elements is a way that provides a general "idea" to the "reader". In programming, our program is the “story” and the problem you are trying to solve is the “idea”.

Computer hardware architecture

The high-level definitions of these parts are as follows:
  • The Central Processing Unit (or CPU) is that part of the computer that is built to be obsessed with “what is next?”. If your computer is rated at 3.0 Gigahertz, it means that the CPU will ask “What next?” three billion times per second. You are going to have to learn how to talk fast to keep up with the CPU.
  • The Main Memory is used to store information that the CPU needs in a hurry. The main memory is nearly as fast as the CPU. But the information stored in the main memory vanishes when the computer is turned off.
  • The Secondary Memory is also used to store information, but it is much slower than the main memory. The advantage of the secondary memory is that it can store information even when there is no power to the computer. Examples of secondary memory are disk drives or flash memory (typically found in USB sticks and portable music players).
  • The Input and Output Devices are simply our screen, keyboard, mouse, microphone, speaker, touchpad, etc. They are all of the ways we interact with the computer.
  • These days, most computers also have a Network Connection to retrieve information over a network. We can think of the network as a very slow place to store and retrieve data that might not always be “up”. So in a sense, the network is a slower and at times unreliable form of Secondary Memory

The building blocks of programs

These constructs are part of every programming language from machine language up to the high-level languages.
  • input:
    Get data from the “outside world”. This might be reading data from a file, or even some kind of sensor like a microphone or GPS. In our initial programs, our input will come from the user typing data on the keyboard.
  • output:
    Display the results of the program on a screen or store them in a file or perhaps write them to a device like a speaker to play music or speak text.
  • sequential execution:
    Perform statements one after another in the order they are encountered in the script.
  • conditional execution:
    Check for certain conditions and execute or skip a sequence of statements.
  • repeated execution:
    Perform some set of statements repeatedly, usually with some variation.
  • reuse:
    Write a set of instructions once and give them a name and then reuse those instructions as needed throughout your program.

General types of errors:

  • Syntax errors:
    These are the first errors you will make and the easiest to fix. A syntax error means that you have violated the “grammar” rules of Python. Python does its best to point right at the line and character where it noticed it was confused. The only tricky bit of syntax errors is that sometimes the mistake that needs fixing is actually earlier in the program than where Python noticed it was confused. So the line and character that Python indicates in a syntax error may just be a starting point for your investigation.
  • Logic errors:
    A logic error is when your program has good syntax but there is a mistake in the order of the statements or perhaps a mistake in how the statements relate to one another. A good example of a logic error might be, “take a drink from your water bottle, put it in your backpack, walk to the library, and then put the top back on the bottle.”
  • Semantic errors:
    A semantic error is when your description of the steps to take is syntactically perfect and in the right order, but there is simply a mistake in the program. The program is perfectly correct but it does not do what you intended for it to do. A simple example would be if you were giving a person directions to a restaurant and said, “... when you reach the intersection with the gas station, turn left and go one mile and the restaurant is a red building on your left.”. Your friend is very late and calls you to tell you that they are on a farm and walking around behind a barn, with no sign of a restaurant. Then you say “did you turn left or right at the gas station?” and they say, “I followed your directions perfectly, I have them written down, it says turn left and go one mile at the gas station.”. Then you say, “I am very sorry, because while my instructions were syntactically correct, they sadly contained a small but undetected semantic error.”.

Terminology:

  • high-level language:
    A programming language like Python that is designed to be easy for humans to read and write.
  • machine language / low-level language:
    A programming language that is designed to be easy for a computer to execute; also called “machine code” or “assembly language.” The lowest level language for software which is the language that is directly executed by the central processing unit (CPU).
  • compile:
    To translate a program written in a high-level language into a low-level language all at once, in preparation for later execution.
  • interpret:
    To execute a program in a high-level language by translating it one line at a time.
  • portability:
    A property of a program that can run on more than one kind of computer.
  • program:
    A set of instructions that specifies a computation.
  • source code:
    A program in a high-level language.
  • bug:
    An error in a program.
  • interactive mode:
    A way of using the i.e. Python interpreter by typing commands and expressions at the prompt.
  • parse:
    To examine a program and analyze the syntactic structure.
  • prompt:
    When a program displays a message and pauses for the user to type some input to the program.
  • semantics:
    The meaning of a program.