PHP & More

A technical blog about programming in PHP and about technology in general: programming, workarounds and troubleshooting

Matplotlib is a MATLAB-like library that allows Python programmers to create images and animations. For example, you can easily draw a graphic representation of functions with Y (and maybe Z) values generated by numpy and scipy functions.
Matplotlib can also be interactive and handle events. The command mpl_connect is used for connecting an event with a callback function.

The Backend Layer

Someone on the IRC has challenged me with questions on how to perform some operations when the window is closed. In addition, I want the window title to be other than the default, “Figure 1”.
enter image description here

Well, the layer that handles the main window is the backend layer,
To find what backend Matplotlib uses, you can add the line
print type(fig.canvas)
The result may be something like:
<class 'matplotlib.backends.backend_gtkagg.FigureCanvasGTKAgg'>
This means that the backend used is ‘GtkAgg’.
With the function ‘dir’, I’ve found that the canvass has a function named get_toplevel, and the returned value of fig.canvass.get_toplevel() is an object of type gtk.Window.
This object has the methods of a GTK window. So you can change its title with the ‘set_titlemethod. For example:
fig.canvas.get_toplevel().set_title(‘Rubic Cube’)
You can tell your application what to do when the user closes the window, by calling its 'connect' method, with 'destroy' for first arguments.
For example:
fig.canvas.get_toplevel().connect(‘destroy’, destroyFunc, ‘Goodbye, cruel world!’)
destroyFunc` is a function that accept 2 arguments (3 if a class member): the widget where the event has occurred and additional user defined data.
More about Python FTK can be found at http://www.pygtk.org/pygtk2tutorial/index.html

Last but not least, you can specify the backend Matplotlib will use, by calling the ‘use’ method of matplotlib.
For example:
matplotlib.use('GTKAgg')

Note: This method should be called before importing ‘pyplot’.

Written with StackEdit.

enter image description here

The other day I downloaded “Fahrenheit 451” by Ray Bradbury as a free eBook, and tried to read it. I found that I cannot read much more than the titles of each chapter.

enter image description here
enter image description here

I tried double-clicking and dragging, and saw that something appears on the screen, organized in paragraphs.

Right Click->Inspect Element

enter image description here
enter image description here
enter image description here

Now, a sub-window is opened at the bottom of the screen:

You can see in that sub-window that some text in English appears in a ‘div’ element just under another ‘div’ element of class ‘textLayer’. To the right of the ‘Inspect Element’ sub-window you can see the CSS rules:

As you can see, the value of property ‘color’ is ‘transparent’, You can edit that property using the color selector or by overriding the text value.
Let’s set it to ‘black’.

Now, you can see the paragraphs.
You can change the opacity property of ‘div.textLayer’ from 0.2 to a higher value (up to 1) in order to read the text better.
Firefox is a great PDF viewer, but my browser couldn’t save the document with the changes: the result was a corrupt file that cannot be opened. I’d written about it to the newsgroup ‘mozilla.wishlist’ found on server ‘news.mozilla.org’. and they opened a ticket.

Before you upload an internet site, you better test it on your local machine. To do that, you should allocate an IP address known as a loopback address that does not require a modem for access. If you’ve installed Apache Httpd server, you’ll probably get an HTML page that reads “It works” upon connecting to “http://localhost” or http://127.0.0.1” from the web browser. But what if you want to create another site? How to make your server recognize an IP?

In this post I will describe by example the process of adding a local IP.

Step 1: Associate an IP with a Domain Name

If you want to create a domain name such as ‘example.coq‘, add a line for it in /etc/hosts in the format:

<inet-addr>   <alias>

For example:

127.0.0.2               example.coq

Step 2: Attach the IP Address To a Network Interface

To make an address available to internet servers, attach it to a network interface.

A network interface is the identifier followed by colons at the beginning of blocks returned by the command ifconfigFor example:

In this block lo0 is an interface name.

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
    options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
    inet6 ::1 prefixlen 128 
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
    inet 127.0.0.1 netmask 0xff000000 

From the prefix ‘lo’ of the interface name, you can know it is a loopback interface.

You can attach an address, login as root, and run ifconfig like in the following example:

ifconfig lo0 127.0.0.2 netmask 255.255.255.255 alias

This will attach IP address 127.0.0.2 to the loopback interface ‘lo0’

You can make the operating system add it each type you start your computer, by adding the following line to /etc/rc.conf:

ifconfig_lo0_alias0="inet 127.0.0.2 netmask 255.255.255.255"

You can learn more about virtual hosts from the section ‘11.6 Virtual Hosts” of the FreeBSD Handbook

Step 3: Start a Listening Server

Now, you can start a server that will listen on your address. You can do it by adding a virtual host in apache httpd, create a server in ‘node.js’, etc.

If you’ve installed ‘Apache24’ from the ports, you can find documentation in '/usr/local/share/doc/apache24'. In addition, you can find documentation in the httpd site.

Written with StackEdit.

One thing I wish to see in languages such as PHP is to find them supporting the complex type. Complex numbers are more than vectors in 2D, and I wish to see expression containing them parsed just like the ones with real numbers. Python supports them, and you have to import ‘cmath’ to use functions of a complex variable. To import cmath type

import cmath

For example, complex numbers are useful in solving cubic equations even if all its roots are real. And cubic equations can be used for Bézier curve manipulations.

Following is the Cardan formula for solving a cubic equation

Be x^3 + ax^2 + bx + c=0 a cubic equation.

Step 1

Convert the equation to the form latex y^3 + py + q = 0
Use the Taylor series formula, to find a k, such that y=x-k:
Be P(x) = x^3 + ax^2 + bx + c
Then, P(x) = P(k) + P'(k)x + {P''(k)x^2 \over 2} + {P'''(k)x^3 \over 6}
P(k) = k^3 + ak^2 + bk + c
P'(k) = 3k^2 + 2ak + b
P''(k) = 6k + 2a
P'''(k) = 6

Because P”(k)=0, 6k + 2a=0, thus:
k= - {a \over 3} .
p=P'(k) = b - {a^2 \over 3}
q=P(k) = {2a^3 \over 27} - {ba \over 3} + c

For example,
x^3 - 7x^2 +14x - 8 = 0
will become
y^3 -2{1 \over 3}y - {20 \over 27} = 0
In Python:

a = -7
b = 14
c = -8
p = b - a**2 / 3.
q = 2*a**3 / 27. - b*a/3. - 8

Step 2

Find 2 numbers u and v that will help us solve the equation. If y=u+v , then the new equation will be:
u^3 + v^3 + (p + 3uv)(u + v) + q = 0
We can find u,v such that (p + 3uv) = 0,
Thus,

and latex u^3 + v^3 = -q
Since p+3uv=0, u^3{v^3} = {-p^3 \over 27}
From both equations, we get that latex u^3 and latex v^3 are the roots of the quadratic equations
t^2 +qt - {q^3 \over 27} = 0
The roots of the quadratic equations are:
(1) u^3 = - {q \over 2} + \sqrt{{q^2 \over 4} + {p^3 \over 27}}
(2) v^3 = - {q \over 2} - \sqrt{{q^2 \over 4} + {p^3 \over 27}}
In Python, the inner root can be computed using:

innerRoot = cmath.sqrt(q**2 / 4. + p**3/27.)

Now, u and v are cubic roots of (1) and (2) respectively. They must satisfy 3uv=-p.
In Python, you get your initial u using:

u=(-q / 2. + innerRoot) ** (1/3.)

If the pair u,v does not satisfy 3uv = -p, you can multiply your v by
$latex-1 + i \sqrt 3 \over 2 $
until the pair satisfies the condition.
Now, having a solution, get the next by multiplying u by $latex-1 + i \sqrt 3 \over 2 and v by latex-1 – i \sqrt 3 \over 2

In our example:
u^3 = {20 \over 54} + \sqrt{{-263 \over 729}}
v^3 = {20 \over 54} - \sqrt{{-263 \over 729}}

Let’s find our three solutions:
u_1= (0.8333333333333335+0.28867513459481187j), v_1=(0.8333333333333335-0.28867513459481187j)
Thus, latex $y_1 = (1.666666666666667+0j)$
u_2 = (-0.6666666666666659+0.5773502691896264j), v_2=(-0.6666666666666657-0.5773502691896264j)
Thus, y_2 = (-1.3333333333333317+0j)
u_3 = (-0.1666666666666676-0.8660254037844383j), v_3=(-0.1666666666666677+0.866025403784438j)
Thus, y_3 = (-0.3333333333333353-2.220446049250313e-16j)

(The above values are output from Python script. The real results look much better.)
Now, to get the roots of the original equation, add k={-a \over 3} to each y.
In our example,
k = 2{1 \over 3}
Thus,
x_1 = 4, x_2=1, x_3=2

Writing expressions is much easier and more readable when the language supports the complex type.

When you see a change in the major version (the number before the first point of the version id), expect a great leap. New features have been added to PHP in version 7, that make programming more convenient. I’m going to discuss some of them.

Null Coalescing

Suppose you’re trying to get a value from a request, and set it to zero if not sent. So instead of typing

$val = $_GET['foo'];
if ($val == null)
  $val=0;

Simply use ?? as follows:

$val = $_GET['foo'] ?? 0;

The Spaceship Comparison Operator

When making a decision based on comparisons between to values, would you like to use a switch command instead of if ... else? Use the operator ‘<=>’ to compare numbers or strings.
$a<=>$b will return one of the following values:
* -1 if $a is smaller than $b
* 0 if $a equals $b
* 1 if $a is greater than $b

Generator Functions

Generator functions have been introduced in PHP 5.5. They allow you to elegantly use generated values in a foreachloop without calling the function time and time again.
For example, the following code:

<?php
function factUpTo($n){
  $genValue=1;
  for ($i=1; $i<=$n;$i++){
    $genValue *= $i;
    yield $genValue;
  }
}

foreach (factUpTo(8) as $j){
  print $j . "\n";
}
?>

produces the following output:

1
2
6
24
120
720
5040
40320

Following are features introduced in PHP 7:

Returned Values

In addition to generating values, a generator can return a value using the return command. This value will be retrieved by the caller using the method getReturn().

For example, the code:


<?php

$gen = (function() {
    yield 1;
    yield 2;

    return 3;
})();

foreach ($gen as $val) {
    echo $val, PHP_EOL;
}

echo $gen->getReturn(), PHP_EOL;

will produce the output:

1
2
3

Delegation

A generator function can generate values using another generator function. This can be done by adding the keyword from after the command yield.
For example, the following code:


<?php
function gen()
{
    yield 1;
    yield 2;
    yield 4;
    yield from gen2();
}

function gen2()
{
    yield 8;
    yield 16;
}

foreach (gen() as $val)
{
    echo $val, PHP_EOL;
}
?>

will produce the following output

1
2
4
8
16

Return Type Declaration

A return type can be declare by adding it at the end of the function declaration after colons.
For example:

function myFunc(): int
{
.
.
.
return $retValue;
}

returns an integer.

Why Write The Return Type At The End?

Two possible reasons to write the type at the end of the declaration and not at the beginning like in Java, C, and other c-like languages:
* In PHP, the function declaration begins with the keyword funcction. The return type is optional.
* This syntax already exists in AcrionScript.

Find more about PHP 7 in the chapter Migrating from PHP 5.6.x to PHP 7.0.x of the php.net site documentation.

Written with StackEdit.

I remember that little prank from the days I was a student. You work on an X terminal, and out of the blue, all the display contents gradually disappear’ Pixel after pixel turns black. But don’t worry – you’ll regain control over your display shortly. shortly.
Everyone can access other X terminal display, and mess with it.

How Does It Work?

This program is a simple one using the GDK library, Gnome’s window management package. Including ‘gdk.h’ will also include:

The Program’s Flow

The main function of the program performs the following steps:
1. Initialize GDK.
2. Create a window whose dimensions are the same as those of the root window.
3. Make the window’s background transparent.
4. Make the window a full-screen window.
5. Add an event handler. to handle Expose events.
The event handler will perform the following steps:
1. Create a list of columns and lengths (number of blackened pixels).
2. Create the Graphics Context for the window.
3. Blacken pixels until all pixels are black.
4. Quit the main loop.

Includes And Structures:

#include <stdio.h>
#include <stdlib.h>  
#include <gdk/gdk.h>

GMainLoop *mainloop;
GList *list;

typedef struct col_and_length_t{
  short col;  // Column number
  short len;  // Number of blackened pixels.
} col_and_length;`

The main function:

int main(int argc, char *argv[]){
  gdk_init(NULL, NULL);
  GdkDisplay *disp=gdk_display_get_default();
  GdkScreen *scr = gdk_display_get_default_screen (disp);
  GdkWindow *root = gdk_screen_get_root_window(scr);
  int rootWidth = gdk_window_get_width(root);
  int rootHeight = gdk_window_get_height(root);
  GdkWindowAttr attr;
  attr.width=rootWidth;
  attr.height=rootHeight;
  attr.x=0;
  attr.y=0;
  attr.window_type = GDK_WINDOW_TOPLEVEL;
  attr.wclass=GDK_INPUT_OUTPUT;

  GdkWindow *newWin=gdk_window_new(root,&attr, GDK_WA_X | GDK_WA_Y);
  gdk_event_handler_set (eventFunc, newWin, NULL);
  GdkRGBA color;
  color.alpha=0;

  gdk_window_set_background_rgba(newWin, &color);
  gdk_window_fullscreen(newWin);
  gdk_event_handler_set (eventFunc, newWin, NULL);
  gdk_window_show(newWin);
  mainloop = g_main_new (TRUE);
  g_main_loop_run (mainloop);
  gdk_display_close(disp);

return 0;
}

The event handler

void start_meltdown(GdkWindow *newWin, int height){
  cairo_t *gc=gdk_cairo_create(newWin);
  cairo_set_line_width(gc,2);
  cairo_set_source_rgb (gc, 0, 0, 0);
  int cell_no,size;
  GList *link;
  col_and_length *link_data;
  size=g_list_length(list);

  while(size>0){
    cell_no=random() % size;
    link = g_list_nth(list,cell_no);
    link_data = (col_and_length *)link->data;
    cairo_move_to(gc, link_data->col, link_data->len);
    cairo_rel_line_to(gc, 0, 1);
    cairo_stroke(gc);
    link_data->len++;
    if (link_data->len >= height){
      list=g_list_remove_link(list, link);
      --size;
    }
  }
  g_main_loop_quit(mainloop);
}

void eventFunc(GdkEvent *evt, gpointer data){
  GdkWindow *newWin = (GdkWindow *)data;
  if (gdk_event_get_event_type(evt) == GDK_EXPOSE && gdk_event_get_window (evt) == newWin){
    int width=gdk_window_get_width(newWin);
    int height=gdk_window_get_height(newWin);
    int i;
    for (i=0; i<width;i++){
      col_and_length *cell=(col_and_length *)calloc(sizeof(col_and_length), 1);
      cell->col=i;
      cell->len=0;
      list = g_list_append(list, cell);
    }
    start_meltdown(newWin,height);
  }

}

Compiling

In linux, compiling a program is easy thanks to the pkg-config command.
Run the following from the command line:

gcc meltdown.c `pkg-config --cflags --libs gdk-3.0` -o meltdown

Now, to run the program type:

./meltdown

Written with StackEdit.

I have received by e-mail a rotated video in the ‘flv’ format. The video was supposed to be a vertical one, but it turned out to be horizontal, that is ROTATED. So, I wrote a little program to rotate it back using libming.
There are two things to take care of when processing the input FLV:

  • The video stream.
  • The sound stream.

Both can be taken from the FLV file.
The code is written in C++, but can be translated easily into PHP. Following is the code:

#include <iostream>
#include <mingpp.h>

using namespace std;

int main(){
  const char *flvFile ="/path/to/inputVideoFile.flv";

  // Get the video stream from the file. The input file can be in the FLV format.
  SWFVideoStream *stream = new SWFVideoStream(flvFile);

  SWFMovie mov (9);  // Create the movie object.

  // The method 'add' returns a display item.
  // Display items can be rotated, transformed, etc.
  SWFDisplayItem *di=mov.add(stream);  

  // Sound streams are taken from a file object. 
  FILE *soundFD = fopen(flvFile, "rb+");
  SWFSoundStream sound(soundFD);

  // The original dimensions of the video are 426 X 240.
  di->rotate(-90);  // Rotate the item 90 degrees clockwise
  di->move(240, 0);  // The rotation moves point (0,240) to (-240,0).


  mov.setSoundStream(&sound,0);  // Add the sound stream at the beginning
                                 // of the movie.

  // Show the frames one by one.
  int noFrames = stream->getNumFrames();
  for (int i=0; i<noFrames; i++)
      mov.nextFrame();

  mov.setDimension(240, 426); // The new dimensions.
  mov.save("/path/to/outputVideoFile.swf", 9);
  cerr<<"Fin\n";
  return 0;
}

This will create a real vertical movie. Don’t share it on YouTube or anywhere you cannot control your movie dimensions.