Wednesday, April 13, 2022

Time Net Speed Monitor on Fire HD 8

Time Net Speed Monitor on Fire HD 8

Notice the speed meter on the top left corner?

Time Net Speed Monitor is an app to show network speed on the display. I want this app because I need to monitor the network speed while streaming video.

This app need "Display over other apps" permission. Some system (Fire OS/Android), doesn't allow the permission to be set, it can be fixed by ADB (Android Debug Bridge).

I try it on Fire HD 8 2020, Fire OS 7.x. Note: The OS version can be found on Settings > Device Options > System updates.

Install on Fire HD 8

Time Net Speed Monitor can be downloaded from Amazon. When you installer, it will ask user to enable "Display over other apps" permission.

Set "Display over other apps" permission

Fire OS > Apps and Notifications > Time NetSpeed Monitor > Advanced: Display over other apps [allow]

Set "Display over other apps" permission through ADB

The permission may be described as "Display over other apps", or "Drawing over other apps".

I was not able to set the permission in Amazon Fire TV Stick. So I use the ADB method. If you don't know how to adb to a Fire OS (or Android), please check how to ADB before continue.

$ adb shell appops set visnkmr.apps.timenetspeed SYSTEM_ALERT_WINDOW allow
OR
adb$ appops set visnkmr.apps.timenetspeed SYSTEM_ALERT_WINDOW allow

To turn off
adb$ appops set visnkmr.apps.timenetspeed SYSTEM_ALERT_WINDOW deny

Wednesday, March 23, 2022

Software Automated Testing and Framework 2

Software Automated Testing and Framework 2

Python and bourne shell script

Follow up with the previous tutorial (a href="http://fuyichin.blogspot.com/2022/03/software-automated-testing-and-framework.html">here), testing framework for Java (JUnit) and C (cmocka). This tutorial continue with Python and bourne shell script.

Python

$ edit calculator.py

#!/usr/local/bin/python3
def plus(a,b):
	return a+b
  
$ edit calculator_test.py
import unittest
import calculator

class CalculatorTest(unittest.TestCase):
	def test_plus(self):
		self.assertEqual(51,calculator.plus(20,30))

if __name__ == '__main__':
	unittest.main()
  

Run the test case:
$ python3 calculator_test.py

  F
======================================================================
FAIL: test_plus (__main__.CalculatorTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/hooichee/workspace/test_maven/python/calculator_test.py", line 6, in test_plus
    self.assertEqual(51,calculator.plus(20,30))
AssertionError: 51 != 50
  

Change the result and run the test case again.

Ran 1 test in 0.000s
OK

Bourne shell script

I am using Shunit2, can be downloaded from https://github.com/kward/shunit2. There are many other testing framework are available, I just use this as an example.

$ edit calculator.sh

#!/bin/sh
plus() {
	echo `expr $1 + $2`
}
$ edit calculator_test.sh
#!/bin/sh
source calculator.sh

testPlus() {
  assertEquals 100 `plus 99 1`
  assertEquals 'Test plus' 50 `plus 20 30`
}

# Load and run shUnit2.
#. ../shunit2
. /usr/local/bin/shunit2

Run test:

$ sh calculator_test.sh 
testPlus

Ran 1 test.

OK

Saturday, March 19, 2022

Software Automated Testing and Framework

Software automated testing and framework

The idea of software automated testing is always there, just how to implement it.

Java has a JUnit testing framework, which looks ok. Other programming languages have their own testing framework, which looks similar.

This is a sample of the output of JUnit:

Tests run: 20, Failures: 0, Errors: 0, Skipped: 0

JUnit 4

JUnit has different versions like version 3, 4, and 5. I am using version 4 as an example here, because it looks simple.

JUnit follow some naming convention and style. The testing program always end with Test, the test case function starts with test. eg. CalculatorTest.testPlus().

If you use maven, JUnit is integrated into the system, just $ mvn test; will do the job. I am using the command line and manual way to shows to create and run the test case.

Let's say this is the program you want to test:

class Calculator {
    int plus(int a, int b) {
        return a+b;
    }
}
    

This is your JUnit test case:

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class CalculatorTest
{
    @Test
    public void testPlus() {
        Calculator cal= new Calculator();
        assertEquals(50, cal.plus(20,30) );
    }
}
Note: JUnit 4 looks simple, need Java 1.5 or above to compile.

$ javac -classpath junit-4.11.jar:. CalculatorTest.java 
⇒ CalculatorTest.class  Calculator.class
$ java -classpath junit-4.11.jar:. CalculatorTest 
⇒ Error: Main method not found in class CalculatorTest
$ java -classpath junit-4.11.jar:. org.junit.runner.JUnitCore CalculatorTest
Exception in thread "main" java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
  
$ java -classpath junit-4.11.jar:hamcrest-core-1.3.jar:. org.junit.runner.JUnitCore CalculatorTest
Time: 0.01
OK (1 test)

The JUnit 4 software can be downloaded from https://github.com/junit-team/junit4/wiki/Download-and-Install

Cmocka for C programm

There is a google testing framework which is more powerful. I choose cmocka, because it is small and simple.

To install:
Debian: $ sudo apt-get install cmocka
macOS: $ brew install cmocka

$ edit calculator.c

int plus(int a, int b)
{
	return a+b;
}

$ edit calculator.h

int plus(int, int);
  

$ edit calculator_test.c

#include 
#include 
#include 
#include "cmocka.h"
#include 
#include 
#include "calculator.h"

static void test_plus(void **state) {
    (void) state; /* unused */
    
    assert_int_equal(50,plus(20,30));
    assert_int_equal(8,plus(5,3));
}

int main(void)
{
    const struct CMUnitTest tests[] = {
        cmocka_unit_test(test_plus),
    };

    return cmocka_run_group_tests(tests, NULL, NULL);
}

To compile and test:
$ cc -c calculator.c
==> calculator.o
$ cc -c `pkg-config --cflags cmocka` calculator_test.c
$ cc -o calculator_test calculator_test.o calculator.o `pkg-config --libs cmocka`

If you don't have pkg-config:
$ cc -c calculator_test.c
$ cc -o calculator_test calculator_test.o calculator.o -lcmocka

==> calculator_test*

Run test case:

./calculator_test 
[==========] Running 1 test(s).
[ RUN      ] test_plus
[       OK ] test_plus
[==========] 1 test(s) run.
[  PASSED  ] 1 test(s).

If integrate with automake. Use libgrowl as an example:
$ git clone https://github.com/fuyichin/libgrowl
$ make check

======================================
Testsuite summary for libgrowl 0.1.0
======================================
# TOTAL: 6
# PASS:  6
# SKIP:  0
# XFAIL: 0
# FAIL:  0
Note: As the time of writing this now, the automake of libgrowl is not integrated into the main branch yet. Can try with the branch autogen.

Other programming like Python and Bourne shell has their own testing framework as well.

Thursday, February 17, 2022

MiTV 4K Enable Debug Mode

MiTV 4K Enable Debug Mode

Settings > About > Build version, click 7 times.
Note: The build version normally is the last info.

{ } Developer option will appear.

{ } Developer option > [x] Developer option 啓用開發者選項 [x] USB debugging USB 調試

A dialog box appear, allow the permission.

Now you can use the ADB:
$ adb connect

The ip address can be found on the network info.

Tuesday, February 08, 2022

Android Grant Drawing Over Other Apps

Android Grant "Drawing over other apps"

Application like SpeedMeter, Assistive Touch may report error or issue about "Drawing over other apps"

You need ADB to grant "Drawing over other apps"


1. find out the package name of the app:
$ adb shell pm list packages

For examples:
com.tuanfadbg.assistivetouchscreenrecorder
visnkmr.apps.timenetspeed

2. grant access
$ adb appops set visnkmr.apps.timenetspeed SYSTEM_ALERT_WINDOW allow

Now you should be able to enable the SpeedMeter or the Assistive Touch apps.

Saturday, January 15, 2022

Tutorial Git branch by examples

Git branch by examples

Git branch sound confusing. This is a jumpstart version, I try to make it as easy as possible

Working with Git branch is easy. Git branch is light-weight. When working with new feature or bug fix, just create a new branch.

Use 'git branch' and 'git checkout':

  Git branch to create branch and show branches:
  format: git branch branch_name
  
  Git checkout to switch between branch:
  format git checkout [-b] branch_name
  

*Important*: Changes before commit exist in the directory (and all branches), after committed the changes will not appear in other branches. The changes after commit will be isolated from other branches. (Will be explained later by example)

Scenario

While working on feature_x, a hotfix needs to be done and released without the feature_x. Should commit feature_x before working on hotfix.

Steps:
1. create branch feature_x and hotfix (from master)
make changes and commit each branch
2. switch between the branches and observe changes are isolated
Note: feature_x started first but not merged yet. Hotfix release first.

      +-- hotfix (add 'hot fix' in README.md file)
  master
      +-- feature_x (add 'feature x' in featurex file)

Git branch and git checkout

In the working directory

$ git branch  # or git branch [--list|-l]
* master  # only 1 main branch
($ git branch -a, shows remote repository branch as well)
$ echo 'Hello, world' > README.txt
  

Create branch feature_x

Create branch:
$ git branch feature_x
$ git branch
feature_x  # feature_x branch was created
* master   # still at master branch
$ git checkout feature_x
$ git branch
* feature_x  # switch to feature_x
master
  

Note: Use 'git checkout -b featurex' to create and switch to branch feature_x.

The new changes are just in the file featurex.

(feature_x)$ echo 'feature x' >> featurex  # make some changes
(feature_x)$ git add featurex
(feature_x)$ git commit -m 'feature x'

(feature_x)$ git log --oneline
be85a75 (HEAD -> feature_x) feature x
9462eec (master) Initial commit

$ git checkou master; git log --oneline
Switched to branch 'master'
9462eec (HEAD -> master) Initial commit# no feature_x committed in the master branch.

The feature_x is not merged into master branch yet. Suddently there is an adhoc bug fix:

(master)$ git checkout -b hotfix
(hotfix)$ ls
README.md  # there is no featurex in this branch
(hotfix)$ echo 'hot fix' > README.md
(hotfix)$ git commit -am 'hot fix'
[hotfix 8cbc155] hot fix
 1 file changed, 1 insertion(+), 1 deletion(-)

(hotfix)$ git branch
  feature_x
* hotfix
  master
(hotfix) git checkout master
(master) cat README.md
==>Hello, world  # changes in hotfix not in master branch, it was isolated.
(master)$ git log --oneline
9462eec (HEAD -> master) Initial commit  # and the commit in other branch is not merge yet.

Merge and delete branch

(master)$ git log --oneline --branches
8cbc155 (hotfix) hot fix
be85a75 (feature_x) feature x
9462eec (HEAD -> master) Initial commit

(master)$ git log --oneline --branches --graph 
* 8cbc155 (hotfix) hot fix
| * be85a75 (feature_x) feature x
|/  
* 9462eec (HEAD -> master) Initial commit

There are 2 branches, merge hotfix just move the HEAD pointer to hotfix, later merge featurex branch, system need a new commit after merging changes in featurex.

(master)$ git merge hotfix
Updating 9462eec..8cbc155
Fast-forward
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
(master)$ git branch -d hotfix  # it is safe to use -d

Note: It is save to use -d, if the branch is not merged, it can not be deleted. Use -D to delete branch that is not merged.

(master)$ git log --oneline --branches
8cbc155 (HEAD -> master, hotfix) hot fix
be85a75 (feature_x) feature x
9462eec Initial commit

You can try to merge feater_x, it needs a new commit, because it need to merge then changes into master+hotfix.

Wednesday, January 05, 2022

Fibonacci One Line Code with Python

Fibonacci One Line Code with Python



This is using recursive and shorthand if to implement fibonacci. Fibonacci is a sequence, the value of the sequence is the sum of the previous 2 numbers in the sequence: eg. 1, 1, 2, 3, 5, 8, 13, 21, ...

The normal Python function:

  def fibonacci(n):
	return 1 if n<=1 else fibonacci(n-1) + fibonacci(n-2)
  

To output:

    for n in range(8):
        print(fibonacci(n))
  

Ok, with the function define, that's 2 lines of code.

Thursday, August 19, 2021

Use Echo Flex As Bluetooth Earphone

Use Echo Flex As Bluetooth Earphone



I found a new usage for Amazon Echo Flex, other than use it as a USB charger. I use Echo Flex as a bluetooth earphone while watching movie at night in the living room, so it doesn't disturb the others.

This is how I do it. I plug in the Echo Flex near the sofa, connect the (wire) eaphone to the Echo Flex with the 3.5mm plug. I connect my TV box to my Echo Flex as external speaker. Then I don't need a long wire earphone. The 3.5mm plug on the Echo Flex can only be used as audio ouput and not input.

I can use a bluetooth earphone, and I have a bluetooth earphone. By using the Echo Flex with a wire earphone, I don't worried about battery life and charging the bluetooth earphone.

Issue. Earlier I can not connect to the Echo Flex via bluetooth from the TV box. The TV box was unable to discover the Echo Flex as a bluetooth device. Then I enable the bluetooth setting of Echo Flex from the Alexa mobile app, then the Echo Flex is discovered by the TV box.

Alexa app > Devices > (Echo Flex) > Bluetooth ...

Once setup completed, the TV box automatically output the audio to Echo Flex (for my case).

Note: The Echo Flex use the bluetooth audio as input or output, but only output through the 3.5mm port.

Wednesday, August 04, 2021

Python: Polymorphism

Python: Polymorphism

A polymorphism in object orinted programming means a same function have more than 1 implementation.

An example of polymorphism in Python:

  > 9*3 ⇒ 27
  > '9'*3 ⇒ 999
  

You can define a multiple function:

  > multiple(9, 3)
  > multiple('9', 3)
  

Different variable type in the parameter produce different output.

Polymorphism: Breathing


class Human(object):
    def breathing(self):
        print('use lungs')

class Fish(object):
    def breathing(self):
        print('use gills')

def breathing(o):
    o.breathing()

alan= Human()
wanna= Fish()
breathing(alan)
breathing(wanna)
⇒ 
use lungs
use gills
  

Another coding:

for o in (alan,wanna):
    breathing(o)
    

Thursday, July 29, 2021

Python Object Oriented Programming Jumpstart

Python Object Oriented Programming Jumpstart



This is the quick and dirty jumpstart object oriented programming for Python. Just for quick start reference.

A simple object

$ edit calculator.py
  
class Calculator(object):
  def plus(self, a,b):  # self refer to the obj itself
	return a+b 

print(Calculator().plus(20,30))
cal= Calculator()
print(cal.plus(2,7))
⇒ 50
⇒ 9

The object in Calculator(object) is just a object variable, it is not used here and will be explained later.
The self in plus(self, a,b) is always there, it is a object variable refer to the object itself, will be explained later. If there is no parameter required in the function just declare f(self) will do.
You can use the Calculator() class itself, or use the cal object created from Calculator() class, eg. Calculator().plus(), cal.plus()

It can be:

class Calculator(object):
  pass
  

There is no implementation in the Calculator() class.


Format: old and new


# old
class Calculator:
  pass

# new
class Greeting(object):  # or class Greeting():
  def hello(self):
    print('Hello, world')

Note:
'pass' means there is not implementation in Calculator() class.


Python: constructor

Constructor use to initialize object.

class Greeting(object):
    def __init__(self):
        print('initialize')
        
    def hello(self):
        print('Hello, world')

a= Greeting()  # ⇒ initialize
a.hello()  # ⇒ Hello, world
  

Python: Inheritance

Python allow multipl inheritance, not discuss here. eg. class obj(parent1, parent2)


class Calculator(object):
  name= 'Calculator'
  def plus(self, a,b):  # self refer to the obj itself
	return a+b 

# inheritance
class ScientificCalculator(Calculator):  # inherit from Calculator
  pi= 3.14
  def circle_area(self, r):
    return  self.pi * r * r

sc= ScientificCalculator()
print(sc.plus(sc.pi,2))
print(sc.circle_area(3))
⇒ 5.14
⇒ 28.26

Scientific calculator(sc) inherit from Calculator() class. The function plus() is not in scientific calculator, but it will be inherited from the parent class(Calculator()).
If you implement a new plus() in Scientific Calculator, it will overwrite the plus() in Calculator() class.
The self.pi refer the pi variable in the local class object, for parent class object use super().name (or Calculator().name)
Try to access pi without self.pi result error, 'name pi is not defined'.


The different between Calculator() and cal object

Calculator().name= 'Scientific Calculator'
cal= Calculator()
cal.name= 'Canon Calculator'

print(Calculator().name)  # ⇒ 'Calculator'
print(cal.name)  # ⇒ 'Canon Calculator'

The Calculator() code follow the previous code.
The cal object name variable change to 'Canon Calculator' but the class (Calculator()) name remain the same.


Another example: Bird

class Bird(object):
    def swing(self):
        print('swing wing')
    def fly(self):
        print('bird fly')

class Penguin(Bird):
    def fly(self):
        print('Sorry, penguin can not fly')

bird= Bird()
bird.fly()
tux= Penguin()
tux.fly()

The Penguin() class inherite from Bird() class. The Penguin().fly() overwrite the Bird.fly(), so penguin can not fly.

Thursday, March 11, 2021

J2ME Jumpstart Tutorial With Wireless Toolkit 2.5.2 Part 2

J2ME Jumpstart Tutorial With Wireless Toolkit 2.5.2 Part 2
compile with the Wireless Toolkit


Using the wireless toolkit


If you already installed the WTK (for Windows, Linux, Mac OS or Solaris), you should able to launch it with ktoolbar command.

$ /usr/local/wtk-2.5.2/bin/ktoolbar


If you use the Linux package to install on macOS, you are not able to build the j2me project. Then follow the command line tutorial (part 3). This tutorial give you a brief understanding of how the j2me project build and run.

Create new project


Create a new project:

New > Project:
Project Name: [ HelloSuite ] / HelloWorld
MIDlet Class Name: [ HelloWorld ]
(To use a different project name can differentiate which field is project name, and which field is class name)

The project will be created at <home>/j2mewtk/2.5.2/apps/HelloSuite (Project name), and the following directory:
src/ # source code here, now empty
lib/ # extra library
res/ # resource
bin/ # package file
classes/ # classes after preverify
tmpclasses/ # classes before preverify
tmplib/

The WTK doesn't include an editor. Use your preferred editor to create src/HelloWorld.java

$ edit src/HelloWorld.java
  import javax.microedition.lcdui.*;
  import javax.microedition.midlet.*;

  public class HelloWorld extends MIDlet
    implements CommandListener {
  private Form mMainForm;
 
  public HelloWorld() {
    mMainForm = new Form("HelloMIDlet");
    mMainForm.append(new StringItem(null, "Hello, MIDP!"));
    mMainForm.addCommand(new Command("Exit", Command.EXIT, 0));
    mMainForm.setCommandListener(this);
  }
 
  public void startApp() {
    Display.getDisplay(this).setCurrent(mMainForm);
  }
 
  public void pauseApp() {}
  public void destroyApp(boolean unconditional) {}
  public void commandAction(Command c, Displayable s) {
    notifyDestroyed();
  }
}
  


Hit the build button, sytem will compile the program in the src directory. If everything goes smoothly, it just shows:

⇒ Build complete
Note: This might not working in Mac OS, because the preverifier on Mac OS is not available. Follow the part 3 to complete the tutorial.
Run the project, program will be displayed in the emulator. If the emulator is not working, can try this j2me emulator https://github.com/hex007/freej2me:

$ jar -jar build/freej2me.jar

Select the HelloSuite.jar

Saturday, March 06, 2021

Apple M1 SSD Isuue 2021

Apple M1 SSD Isuue 2021


There are stories reported that the new Apple M1 mac write more on SSD than usual. Shorten the life span of Mac to 2-5 years time.

https://www.gizmochina.com/2021/02/24/apple-m1-mac-users-face-severe-ssd-degradation-report/

Thursday, February 18, 2021

HP mini 1000 Reborn 2021

HP mini 1000 Reborn 2021


HP mini 1000 is my AE86 (Initial D), Atom CPU, 1+1Gb Ram, it was pre-installed with Windows 7(?), later I changed it to Hackintosh Snow Leopard, and now it is running Raspberry Pi Desktop OS (Debian 10 Buster).

Plastic casing, but good build quality.

HP mini 1000 has many similar variant. The series I am refering has 2 version, the normal black color swirl pattern, and the red color Vivienne Tam special edition 紅牡丹. Mine is black.

Vivienne Tam 譚燕玉 is a fashion designer, settle in New York now. Her design inspired with her Chinese culture background.

HP mini has the best *netbook keyboard*. Netbooks are small in size, but this HP mini keyboard is bigger and easier to type.

Cnet review here

Youtube

HP mini 1000 http://fuyichin.blogspot.com/2008/12/hp-mini-1001tu-hardware.html

HP mini Vivienne Tam 2nd edition. https://fuyichin.blogspot.com/2010/07/hp-mini-210-vivienne-tam-edition.html

J2ME Jumpstart Tutorial With Wireless Toolkit 2.5.2

J2ME Jumpstart Tutorial With Wireless Toolkit 2.5.2


Introduction


I am late by 20 years, but I believe there are still some values with this old software.

In Java 1.2, Java split into 3 categories, J2SE, J2EE and J2ME. J2SE (Standard Edition) is the original Java from Java 1.1. J2EE (Enterprise Edition) is for building server side web application. J2ME (Micro Edition) is a subset of J2SE, with a small footprint to run on mobile and other microprocessors platform.

J2ME was designed to run on low memory and storage, 512k ram or less. In real implementation J2ME vm can runs on 8k ram (as stated in squawk documentation).

J2ME has a configuration base and a profile (J2ME=Configuration+Profile). There are 2 configurations in J2ME, CLDC and CDC. CLDC (Connected Limited Device Configuration) with a smaller footprint. There are more profiles available, the most common is MIDP.

This tutorial focus on CLDC+MIDP.

Software you need to compile MIDP program


1. Java jdk compiler (Java SE)
2. Sun wireless toolkit (which includes CLDC configuration, MIDP profile, preverifier and emulator).

The process to compile MIDP program:
1. compile with java compiler.
2. preverify with the preverifier.
3. package into j2me package.

Sun wireless toolkit 2.5.2


The Sun wireless toolkit (WTK 2.5.2) is a very old software. It might not runs on your system. I have tried on macOS (High Sierra) and Linux (Raspberry Pi Desktop OS), encounter some issues but there are workaround for it.

Download from the Oracle website https://www.oracle.com/java/technologies/java-archive-downloads-javame-downloads.html. Choose your OS platform. There is no macOS platform for WTK 2.5.2, just the Linux version to install.

Install (macOS)
$ chmod +x sun_java_wireless_toolkit_xxx_.bin.sh
$ ./sun_java_wireless_toolkit_xxx_.bin.sh

Read the license. Do you agree to the above license terms? [yes or no] yes
Specify a path to Java interpreter directory: [ /Library/Java/Home ]
(I use /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home )
Directory to install the toolkit: /usr/local/wtk-2.5.2

Test the installation
$ cd /usr/local/wtk-2.5.2
$ bin/ktoolbar
⇒ error
Mac/ktools.properties (no such file)

$ cp lib/Linux/ktools.properties lib/Mac/ktools.properties
$ bin/ktoolbar


to be continue... next will talk about how to write and compile a j2me midp program.

Thursday, February 11, 2021

Python Example Show Big2 Cards Order

Python Example: Show Big2 Cards Order



How to print out the big2 card order in Python?

> cards= list(range(52))
> cards.sort(key=lambda x:(x+12)%13*4+x//13)

[1, 14, 27, 40, 2, 15, 28, 41, 3, 16, 29, 42, 4, 17, 30, 43, 5, 18, 31, 44, 6, 19, 32, 45, 7, 20, 33, 46, 8, 21, 34, 47, 9, 22, 35, 48, 10, 23, 36, 49, 11, 24, 37, 50, 12, 25, 38, 51, 0, 13, 26, 39]

Diamond-23456789TJQKA Club-23456789TJQKA ...

The code id 1 mean D3, 14-C3, 2-D4...39-Spade2

The 2 lines of python code looks simple, but hard to read and understand. I will show you how to do it step by step.

Normal card


First I create a deck of normal cards (52 cards), assign an id for each card from 0..51. Starts from Diamond suit 0-10, JQKA, then Club, Heart and finally Spade. The id does not show the card order by value. The order by value should be D2,C2,H2,S2,... D3,C3…, DA(Diamond Ace), CA, HA, SA.

$ edit card.py
# poker card program

def get_card_name(card):
    ''' pass in the card value, return card name eg. D3-Diamond 3, ST-Spade 10, HA-Heart Ace '''
    suit= ''  # Diamond, Club, Heart or Spade
    value= 0
    if card>=0 and card<13:
        suit= 'Diamond'
    elif card>=13 and card<26:
        suit= 'Club'
    elif card>=26 and card<39:
        suit= 'Heart'
    else:
        suit= 'Spade'
    
    value= (card % 13) + 2
    if value==11:
        value= 'J'
    elif value==12:
        value= 'Q'
    elif value==13:
        value= 'K'
    elif value==14:
        value= 'A'
    else:
        pass
    
    return (suit,value)

def show_hand(cards):
    ''' show cards on hand '''
    for card in cards:
        print(get_card_name(card))

def get_card_value(card):
    ''' convert id 0..51 to value eg. D2=0, C2=1, H2= 2, S2=3, D3= 4 '''
    suit= card//13
    value= card%13
    return value*4+suit
get_card_name() shows a more readable card name:
> get_card_name(0) ⇒ ('Diamond',2)

show_hand() shows all the cards in a list:
> show_hand([0,8,23,24,44])
('Diamond', 2)
('Diamond', 10)
('Club', 'Q')
('Club', 'K')
('Spade', 7)

get_card_value() return the actual value or the card. eg. D2-0 C2-1,...
> cards= list(range(52))
> cards.sort(key=get_card_value)
> show_hand(cards)
('Diamond', 2)
('Club', 2)
('Heart', 2)
('Spade', 2)
('Diamond', 3)
...
('Heart', 'A')
('Spade', 'A')

Big2 card


In the big2 game, 2 is the largest value in a suit. So the order is Diamond 3456789TJQKA2. To sort the cards, you need a new function to replace the get_card_value().
$ edit big2_card
from card import show_hand

def get_big2_value(card):
    ''' D3=0 C3 H3 S3 D4 ... SA D2 C2 H2 A2 '''
    ''' id 1=D3 5=C3 9=H3 13=D4 '''
    suit= card//13
    value= (card+12)%13  # change 2 as the largest value
    return value*4+suit

cards.sort(key=get_big2_value)
show_hand(cards)  
  

⇒ [1, 14, 27, 40, 2, 15, 28, 41, 3, 16, 29, 42, 4, 17, 30, 43, 5, 18, 31, 44, 6, 19, 32, 45, 7, 20, 33, 46, 8, 21, 34, 47, 9, 22, 35, 48, 10, 23, 36, 49, 11, 24, 37, 50, 12, 25, 38, 51, 0, 13, 26, 39] (means [D3, C3, ... S2])

('Diamond', 3)
('Club', 3)
('Heart', 3)
('Spade', 3)
('Diamond', 4)
...


Use sort with Lambda



Lambda function format: f= lambda x: x*x. The lambda function only have 1 return expression, is this case it is x*x.
> f(5) ⇒ 25

> cards= list(range(52))
> # cards.sort(key=get_big2_value)
> cards.sort(key=lambda x:get_big2_value(x))

It also can be written as
> cards= list(range(52))
> cards.sort(key=lambda x:(x+12)%13*4+x//13)

Note: The expression evaluated from get_big2_value(), is hard to read. Referring to get_big2_value() should be easier.

Thursday, February 04, 2021

An Interesting Experience To Install Software On Windows 7

An Interesting Experience To Install Software On Windows 7


My Windows 7 is for fun, it is outdated, sitting there for several years doing nothing. I just want to play around with it before I upgraded to Windows 10. To install some software like Java, Growl and Python.

After having some fail attemps, I feel like Windows system is a big pile of junks messy software code, around 15-20Gb, but still can find something useful out of it.

The process is interesting, so I write it down.

Software Package Manager


The original software manager from Windows is always not good. The first things I am doing is install a 3rd party software manager tools to help me to get the job done. I have tried Scoop many years ago, now I want to try something else, there are quite a few 3rd party tools available, like Chocolatey, OneGet, AppGet. All fail to be installed as Windows 7 is just too old.

Microsoft came out a new software manager, WinGet on May 2020, it is new and only support Windows 10. It is a copycat of AppGet. So my first choice is try AppGet.

AppGet


AppGet fail for the first time, it was unable to download and update the dot net framework. AppGet base on .Net. Later I try the second time, it was able to download the dot net framework. It says AppGet was installed, but I can't find the appget.exe!!

Chocolatey


Let's try Chocolatey. Requirement Windows 7+, PowerShell v2+, sounds good to go.

There are a few methods to install, first try install from PowerShell. It says need PowerShell v3, mine is v2.

PS C:\> Get-Host
==> Version: 2.0

Try Basic Cocolatey Install: cmd


@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"

Exception calling "DownloadString" with "1" argument(s): "The underlying connec tion was closed: An unexpected error occurred on a send."
At line:1 char:54
+ iex ((New-Object System.Net.WebClient).DownloadString <<<< ('https://chocolat ey.org/install.ps1'))
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException


Try PowerShell, fail.

PowerShell


Try upgrade to PowerShell. I have tried a few times before successfully updated to PowerShell 5.

You can try by installing the WMF 5.1 https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/wmf/setup/install-configure?view=powershell-7.1#download-and-install-the-wmf-51-packagePowerShell 5

Scoop


I have tried Scoop before, it was working, but now it says it need PowerShell v5.

Try to upgrade to PowerShell v5, but install Windows Management Framework 5.1 fail! (I have tried a few more times before I succeed)

PS C:\> iwr -useb get.scoop.sh | iex
iwr : The request was aborted: Could not create SSL/TLS secure channel.
At line:1 char:1
+ iwr -useb get.scoop.sh | iex
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], W...
eption
+ FullyQualifiedErrorId :
WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand


You need to upgrade PowerShell to get it work. In my opinion, is not a good idea to write the installation script, rely on PowerShell.

Python: missing DLL


I have tried a few version 3.7, 3.8, 3.9, 32bit and 64bit version, all having 1 problem:

Error:Error: api-ms-win-core-path-l1-1-0.dll is missing from your computer…...

No luck, still unable to solve.

FULL STOP. Oh Microsoft!!!

Thursday, January 28, 2021

Java libgrowl Revisit

Java libgrowl Revisit



This time I am going to write my own Java program with libgrowl GrowConnect class, just take it as an exercise.

First you need to get a copy of the libgrowl or you can compile on your own. There are at least 2 sources for the program:

classic https://github.com/feilimb/libgrowl
maven https://github.com/sbower/libgrowl

Write a GrowlNotify program to accept message, tittle, host, application name, notification name as parameters. Minimal to provide message as parameters, others are optional.
eg. $ GrowlNotify 'Hello, world.'

import net.sf.libgrowl.GrowlConnector;
import net.sf.libgrowl.Application;
import net.sf.libgrowl.Notification;
import net.sf.libgrowl.NotificationType;

class GrowlNotify {
	public static void main(String[] args) {
		if (args.length<1) {
			System.out.println("Usage: TestGrowlNotify <message> [<title> <host> <application> <notification>]");
			System.out.println("eg. TestGrowlNotify 'Hello, world.'");
			System.exit(0);
			}

    int counter= 0;
    int i;
    String message="", title="", host= "localhost", appName="libgrowl", notificationName="libgrowl";
    GrowlConnector growl;
    Application application;
    Notification notification;
    NotificationType notificationType;
    NotificationType[] notificationTypes;

    for (i=0; i<args.length; i++) {
      switch(counter++) {
      case 0:
        message= args[0]; break;
      case 1:
        title= args[1]; break;
      case 2:
        host= args[2]; break;
      case 3:
        appName= args[3]; break;
      case 4:
        notificationName= args[4]; break;
      default:
        break;
      }
    }

    application = new Application(appName);
    notificationType = new NotificationType(notificationName);
    notificationTypes = new NotificationType[] { notificationType };

    growl= new GrowlConnector(host);
    growl.register(application, notificationTypes);
    notification = new Notification(application,
        notificationType, title, message);
    growl.notify(notification);

    }
}



$ java -cp libgrowl.jar GrowlNotify.java
⇒ GrowlNotify.class
$ java -cp libgrowl.jar GrowlNotify 'Hello, world.'


If Growl software is installed and running, it shows "Hello, world.".

Just sample

Maven


I am using maven 3.6. Add dependency in pom.xml file:


<dependencies>
...
<dependency>
<groupId>net.sf</groupId>
<artifactId>libgrowl</artifactId>
<version>0.5</version>
</dependency>
<dependencies>


Copy libgrowl.jar to ~/.m2/repository/net/sf/libgrowl/0.5/.


$ cp libgrowl.jar ~/.m2/repository/net/sf/libgrowl/0.5/.
$ mvn compile
$ mvn exec:java -Dexec.mainClass="com.example.GrowlNotify" -Dexec.args="'Hello, world.'"

Saturday, January 16, 2021

Signal Server Down Due To Subscribers Surge

Signal Server Down Due To Subscribers Surge

Signal messenger down today for few hours, unable to send message through Signal desktop and iPhone, but Android seems ok.

According to the news, Signal server down due to surge in subscribers.

Don't know this is good news or bad news for Signal.

The Indian Express: Signal is down, unable to cope with influx of new users.

BBC News: WhatsApp changes: Signal messaging platform stops working as downloads surge.

Friday, January 15, 2021

Intel Change CEO 2020

Intel Change CEO 2020


Intel ousts BoB Swan as CEO and replaced with Pat Gelsinger. Pat Gelsinger was CEO of VMWare.

Intel is not important anymore, why am I writing this? Just for recording purpose.

There was one time, everyone was using Intel chips, especially when Apple switched to Intel. Windows, Mac OS, Linux, even SUN Solaris can run on Intel chips.

Now Wintel (Windows-Intel) alliance is not as strong bonded as before, Microsoft has tried to run Windows on ARM platform. Many others will follow Apple footsteps, switching to ARM base platform. Even Linux developers are focusing more on the ARM platform as well.

Intel semiconductor production can't match with Taiwan TSMC. Taiwan TSMC already mass production with 5nm, while Intel still with 7nm (refer Intel's 7nm is Broken here). Intel is not so experienced in SoC, where CPU, GPU and memory are integrated into 1 chip.

Intel still can do 1 more thing, license ARM instruction sets and make their own ARM chips. Qualcomm has their own ARM based chips, SnapDragon. Amazon has its own ARM server offer with their AWS services called Graviton2.

Intel owned ARM CPU before, which is StrongARM and renamed to XScale, that was around year 2000. StrongARM is a product of Digital Equipment Corporation that works together with ARM. Intel acquired StrongARM as a settlement of a lawsuit with DEC.

StrongARM/XScale chips are used in some mobile devices like the HP iPAQ handheld device. Intel decided to sell off StrongARM/XScale to Marvell Technology and focus on its own low power Atom cpu. I don't see Atom cpu going anywhere now.

Intel is going down trend and going nowhere, if Intel is not going to do something right, it is just a matter of time.

Reference:
https://edition.cnn.com/2021/01/13/investing/intel-new-ceo-pat-gelsinger/index.html

Thursday, January 14, 2021

Zoom meeting on Echo Show 8

Zoom meeting on Echo Show 8

Zoom at home service comes to Google Nest Hub Max and Amazon Echo Show 8. It is different from the Alex for Zoom Rooms skill.

To make it simple, it means user can join Zoom meeting with Echo Show 8 (but not Echo Show 5).

There are a few ways to join a Zoom meeting from Echo Show, you can get it from the official website for the detail instructions. For me I take some simple steps:

"Alexa, open Zoom meeting"
Join a zoom meeting with ID. This ID is from the host, or the URL of the zoom meeting. I don't even sign on to Zoom.

If the simple steps doesn't work, follow the help from Zoom support.

My short review of using Zoom meeting on Echo Show 8. User interface and fuctions are quite similar with the Zoom application on desktop. Can change the view, mute audio, disable video. Unable to chat with text, but can received text from the others. I am happy with it.

Zoom at home works on Echo Show 8 and not Echo Show 5, not sure about Echo Show 10. Since Show 10 is newer device, expect Zoom will worked on Show 10, if it doesn't for now.