Monday, June 28, 2021

Leetcode, 46 - Permutation

How to solve Leetcode, 46 permutation?

Let's see a easy way to solve with tree breadth first solution.

For example : [1, 2, 3]

The approach : take an item each time to insert into in between array.

1: [ [1] ]
   Insert the first number.

2: [ [1] ]
    ^   ^

   Insert 2 before and after 1.
   [[2,1],[1,2]]


3: 
    [
      [3,2,1],[2,3,1],[2,1,3],
      // place 3 around and between [ 2,1 ]
                                     ^ ^ ^
      [3,1,2],[1,3,2],[1,2,3]
      // place 3 around and between [ 1,2 ]
                                     ^ ^ ^
    ]

Hope this approach is easy to understand.

 

var permute = function(nums) {

  //init results with first numbers
  let results = [[nums[0]]];

  //loop through the rest of numbers
  for (let i = 1i<nums.length;i++) {
    let num = nums[i];
    let tmp=[];

    //loop through each item in the results
    for (let j=0;j<results.length;j++) {
      let result = results[j];

      //insert the current number around/in-between
      for (let k=0;k<=result.length;k++) {
        let head = result.slice(0,k);
        let tail = result.slice(k);
        tmp.push([...headnum, ...tail]);
      }
    }
    results = tmp;
  }
  return results;
};

       

 






Thursday, June 24, 2021

List

Create Empty List
JS Python
let arr = [];
arr = []

Create list with size:
let arr = new Array(5);
arr = [None] * 5


Add an item at the end
arr.push(1);
arr.append(1);

Add an item at the begin:
arr.unshift(2);
arr.splice(0, 0, 2);
arr[:0]=[2]
arr.insert(0,2)

Add items inside:
arr.splice(2,0,3,4);
arr[1:0]=[3]

Add 2 arrays:
let arr3 = arr1.concat(arr2);
arr3 = arr1 + arr2
arr = [...arr, ...otherArr];
arr = [*arr, *otherArr]
arr.extend(otherArr)

Delete Items at the end
arr.pop();
arr.pop()

Delete items at the begin:
arr.splice(0,1);
arr[0:1]=[]

Delete items at the begin and return the deleted item
arr.shift();
arr.pop(0)

Delete Items inside (delete one item in index 1):
arr.splice(1,1);
arr[1:2]=[]
arr.pop(1)

Initial values:
arr = new Array(5).fill(0);
arr = [0] * 5

Range:
[...Array(5).keys()].map(i=>i+5);
list(range(5,10)

Get first item:
arr[0]
arr[0]

Get last item:
arr.slice(-1)[0];
arr[-1]

Get first N items:
arr.slice(0, N);
arr[0: N]

Is list?
Array.isArray(arr)
isinstance(arr, list)

String to list:
arr = s.split("");
arr = [...s];
arr = list(s)

List to string
s = arr.join("");
s = "".join(arr)

Tuesday, June 22, 2021

Leetcode question 57

LeetCode Insert Interval :

Here is my solution. It's break a loop into three sections:

1. Find the new begin number to construct new interval.

2. Find the new end number to construct new interval.

3. Append the remaining items into new interval.

Hope this make sense.
Also, hope those if/else conditions can be more straight forward.


/**
 * @param {number[][]} intervals
 * @param {number[]} newInterval
 * @return {number[][]}
 */
 var insert = function(intervalsnewInterval) {
    let begin = newInterval[0];
    let end = newInterval[1];
    let result = [];
    let tmpInterval = [];
    let len = intervals.length;
    let i = 0;

    if (len == 0) {
        return [newInterval]
    }

    // 1. insert begin position
    for (i = 0i < leni++) {
        let interval = intervals[i];
        if (begin <= interval[0]) {
            tmpInterval[0] = begin;
            break;
        } if (begin > interval[0] && begin <= interval[1]) {
            tmpInterval[0] = interval[0];
            break;
        } else if (begin > interval[1]) {
            result.push(interval);
            if (i===len-1){
                result.push(newInterval);
            }
        }
    }

    // 2. insert end position
    for (; i < leni++) {
        let interval = intervals[i];
        if (end < interval[0]) {
            tmpInterval[1] = end;
            result.push(tmpInterval);
            break;
        } else if (end <= interval[1]) {
            tmpInterval[1] = interval[1];
            result.push(tmpInterval);
            i++;
            break;
        } else if (end > interval[1]) {
            if (i===len-1) {
                tmpInterval[1] = Math.max(interval[1], end);
                result.push(tmpInterval);
            }
            continue;
        }

    }

    // 3. remaining interval
    for (; i < leni++) {
        let interval = intervals[i];
        result.push(interval);
    }

    return result;
};

Try to get one step further. Now, just put newInterval into array in order.
Then swap the end number.
The logic in here is getting more straight forward.

/**
 * @param {number[][]} intervals
 * @param {number[]} newInterval
 * @return {number[][]}
 */
 var insert = function(intervalsnewInterval) {
    
    let len = intervals.length;
    // base cases
    if (len == 0) {
        return [newInterval]
    }
    if (newInterval[1] < intervals[0][0]) {
        return [newInterval, ...intervals];
    }
    if (newInterval[0] > intervals[len-1][1]) {
        return [...intervalsnewInterval];
    }

    // merge newInterval into interval in order, 
    // but the end number
    let found = false;
    let tmpIntervals=[]
    for (let i=0i<leni++) {
        let interval = intervals[i];
        if (!found && newInterval[0] <= interval[0]) {
            tmpIntervals.push([...newInterval]);
            found = true;
        }
        tmpIntervals.push([...interval]);
    }
    if (!found) {
        tmpIntervals.push([...newInterval]);
    }

    // fix the end number by swapping
    let last = tmpIntervals[0];
    let result = [last];
    for (let i=1i<tmpIntervals.lengthi++) {
        let interval = tmpIntervals[i];
        if (interval[0]<=last[1]) {
            last[1] = Math.max(last[1], interval[1]);
        } else {
            last = interval
            result.push(last);
        }
    }
    return result;
};







Sunday, June 20, 2021

Two diminsion array

Initial two dimension array with 0L

 > arr = Array(2).fill(Array(10).fill(0));
[
  [
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0
  ],
  [
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0
  ] 

However, assign a data that populate all rows in that position.

> arr[1][2]=3;
3
> arr
[
  [
    0, 0, 3, 0, 0,
    0, 0, 0, 0, 0
  ],
  [
    0, 0, 3, 0, 0,
    0, 0, 0, 0, 0
  ]
]


Initial two dimension array with sequence number:

 > arr = Array(2).fill(Array(10).fill(0)).map((a,i)=>a.map((b,j)=>i*10+j));
[
  [
    0, 1, 2, 3, 4,
    5, 6, 7, 8, 9
  ],
  [
    10, 11, 12, 13, 14,
    15, 16, 17, 18, 19
  ]
]

Reassigning a data is fine in here.

 > arr[1][2] = 77;
77
> arr
[
  [
    0, 1, 2, 3, 4,
    5, 6, 7, 8, 9
  ],
  [
    10, 11, 77, 13, 14,
    15, 16, 17, 18, 19
  ]
]



Saturday, June 19, 2021

Node.js end event

Another practice of hankerrank today, this is the problem in windows :

process.stdin.on('end', function() {...}

 The fix is :

process.on('SIGINT', function() {
...
exit(0);

 And, use CTRL+C to end the process.

Wednesday, June 09, 2021

AWS Labmda

Looking at my  lambda error. Dose aws lambda support node.js ES6?

 

2021-06-09T00:50:21.381Z    undefined    ERROR    Uncaught Exception     {
    "errorType": "Error",
    "errorMessage": "Must use import to load ES Module: /var/task/lambda.js\nrequire() of ES modules is not supported.\nrequire() of /var/task/lambda.js from /var/runtime/UserFunction.js is an ES module file as it is a .js file whose nearest parent package.json contains \"type\": \"module\" which defines all .js files in that package scope as ES modules.\nInstead rename lambda.js to end in .cjs, change the requiring code to use import(), or remove \"type\": \"module\" from /var/task/package.json.\n",
    "code": "ERR_REQUIRE_ESM",
    "stack": [
        "Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /var/task/lambda.js",
        "require() of ES modules is not supported.",
        "require() of /var/task/lambda.js from /var/runtime

...
 

In the package.json,

{

    "type":"module"

}

This is how I get my ES6 import syntax work in node.js, but not serverless.

To resolve this issue, install esm package npm install esm.
Also remove "type":"module" in package.json.



Tuesday, June 08, 2021

Elasticsearch

I have my elasticsearch in my window services. I only start up this service when I need it.

To see all elasticsearch index in the local, open browser to
http://localhost:9200/_cat/indices?v

To view a particular index data, open browser to
http://localhost:9200/[index name]/_search

For example: my earthquakes data
http://localhost:9200/earthquakes/_search
The data is in hits.hits.

 

Use bulk function to insert multiple records.
To avoid the data duplication when inserting, apply the same _id.

    let body = earthquakes.flatMap(
        obj => [{ index: { _index: INDEX_id: obj.id } }, obj]
    );
    let results = await client.bulk({ 
        refresh: true,
        body
    });

Wednesday, June 02, 2021

Django & celery

RSS project with Django and Celery

The repository is in https://github.com/ccapeng/rss_django

Some quick notes about of how to apply celery task work on windows. That took me a while to get it right.

1. The latest celery issue I have in the runtime

ModuleNotFoundError: No module named 'grp'

The solution is to rollback the early version: 

pip uninstall celery
pip install celery==5.0.5

 

2. The project is rss with one app feed.

To learn how to move around task to app, please check the project.

To run worker on windows,
celery -A feed worker --loglevel=info -P solo

Not celery -A feed worker --loglevel=info

Not celery -A feed worker --loglevel=info -P eventlet
This command come out threading error messages on windows.

To start scheduler,

celery -B feed beat


3, For Windows support, you can check with community discussion at

https://www.reddit.com/r/django/comments/lmilwl/the_proper_way_to_get_celery_to_work_on_windows/

 

Sunday, May 30, 2021

Django log

Use 2 logger patterns: django and django.db.backends.
Need to make sure to add 'propagte': False to django.db.backends
Otherwise, the db log will show twice.


# Separate DB SQL log from django log
LOGGING = {
    'version'1,
    'filters': {
        'require_debug_true': {
            '()''django.utils.log.RequireDebugTrue',
        }
    },
    'handlers': {
        'db_handler': {
            'level''DEBUG',
            'filters': ['require_debug_true'],
            'class''logging.StreamHandler',
            'formatter''db_format'
        },
        'log_handler': {
            'level''DEBUG',
            'filters': ['require_debug_true'],
            'class''logging.StreamHandler',
            'formatter''log_format'
        }
    },
    'loggers': {
        'django': {
            'handlers': ['log_handler'],
            'level'os.getenv('DJANGO_LOG_LEVEL''INFO'),
        },
        'django.db.backends': {
            'level''DEBUG',
            'handlers': ['db_handler'],
            'propagate'False
        },
    },
    'formatters': {
        'db_format': {
            'format''sql> %(message)s'
        },
        'log_format': {
            'format''django> %(message)s'
        }
    }
}


In a api request, the console show logs like this:


Django version 3.2.3, using settings 'bookstore_openapi.settings'
Starting development server at http://0.0.0.0:8001/
Quit the server with CTRL-BREAK.
sql> (0.000) SELECT "book_book"."id", "book_book"."title", "book_book"."category_id", "book_book"."publisher_id", "book_book"."author_id" FROM "book_book" WHERE "book_book"."id" = 1 LIMIT 21; args=(1,)
django> "GET /api/books/1 HTTP/1.1" 200 72

 

 

 

Monday, May 17, 2021

Github main/master branches

Today, I just found out why my git pull not always up to day. Then, I found out not my current working "main" branch.

The main branch is just like come out of middle of somewhere with shorter life.

To fix the git pull issue, the easy way is just go to github repository setting > branches, then fix the default branch.





Saturday, May 15, 2021

Response and JSONResponse

JsonResponse is from vanilla django.

Response is from restframework.

I have code in the following respectively.

from django.http.response import JsonResponse
 
from book.models import Publisher
from book.serializers import PublisherSerializer



def get_publisher(publisher):
    publisher_serializer = PublisherSerializer(publisher
    return JsonResponse(publisher_serializer.data) 

 

from rest_framework.response import Response
 
from book.models import Publisher
from book.serializers import PublisherSerializer


def get_publisher(publisher):
    publisher_serializer = PublisherSerializer(publisher
    return Response(publisher_serializer.data)

What are the differences?

 In the settings, I have REST_FRAMEWORK overwritten.

REST_FRAMEWORK = {

    'DEFAULT_RENDERER_CLASSES': (
        'utils.api.renderers.CamelCaseJSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ),

    'DEFAULT_PARSER_CLASSES': (
        'utils.api.parsers.CamelCaseJSONRenderer',
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser'
    ),
}

That is the conversion between snake case and camel case for all the keys of json.
In the python, we use snake case for all the variable naming.
In the json, the convention is camel case.

In order to have the case conversion work, the Response from rest_framework.response should be used in here.






 

Sunday, May 09, 2021

Node.js and Elastic Search

There are two elastic search node.js packages: elasticsearch and @elastic/elasticserach.
Both works. Feel confusing?

According to https://openbase.com/categories/js/best-nodejs-elasticsearch-libraries?orderBy=RECOMMENDED&,
looks like @elastic/elasticsearch is the chosen one now.


Wednesday, March 24, 2021

Python Sort with multiple keys

This is the sample when sorting with multiple keys in descending order.

    cars = [
      {'car''Ford''year'2005},
      {'car''Mitsubishi''year'2000},
      {'car''Buick''year'2018},
      {'car''Buick''year'2019},
      {'car''BMW''year'2019},
      {'car''Faraday''year'2014},
      {'car''VW''year'2011},
      {'car''Lincoln''year'2017},
    ]
    print("cars")
    print(*cars, sep="\n")
    cars_sorted = sorted(cars, key = lambda x: ([-ord(c) for c in x["car"]], -x["year"]))
    print("sorted cars")
    print(*cars_sorted, sep="\n")

For string to do reversed order, a little trick is to convert character to ascii code number.

{'car': 'VW', 'year': 2011}
{'car': 'Mitsubishi', 'year': 2000}
{'car': 'Lincoln', 'year': 2017}
{'car': 'Ford', 'year': 2005}
{'car': 'Faraday', 'year': 2014}
{'car': 'Buick', 'year': 2019}
{'car': 'Buick', 'year': 2018}
{'car': 'BMW', 'year': 2019} 


 


Tuesday, February 23, 2021

Merge K sorted array

This is LeetCode problem 23: merge K sorted array.

The solution is to use heap to merge sub array.

I provide three kinds of solution. Use the second solution to pass LeetCode.



Saturday, February 20, 2021

Link Image in Linkedin

 I want to link my web site and github to linkedin, but I found a missing site thumbnail.

To fix that, I need to add tag like

<meta property="og:image" content="image url" />

in gatsby project > components > seo.js.

      meta={[
        {
          name: `description`,
          content: metaDescription,
        },
        {
          property: `og:title`,
          content: title,
        },
        {
          name: "image",
          property: `og:image`,
          content: thumbnail,
        },
        {
          name: "description",
          property: `og:description`,
          content: metaDescription,
        },
        {
          property: `og:type`,
          content: `website`,
        },
        {
          name: `twitter:card`,
          content: `summary`,
        },
        {
          name: `twitter:creator`,
          content: site.siteMetadata?.author || ``,
        },
        {
          name: `twitter:title`,
          content: title,
        },
        {
          name: `twitter:description`,
          content: metaDescription,
        },
      ].concat(meta)}

Since both title and description are data loaded from gatsby-config.js

So I try to add image into configuration. However, the image path can not be transpiled correctly.

The correctly way to do that is import image:

import thumbnail from '../images/monster.png' 

After redo, I have thumbnail shown now.







 

 

 

 




Monday, February 15, 2021

heroku deployment

 Few lessons I learned when I deployed react apps.

  1. Show to start up:
    Need to switch another buildpacks intead of heroku default node.js
    heroku buildpacks:set mars/create-react-app -a <appname>
  2. Error of no web process:
    at=error code=H14 desc="No web processes running" method=GET path="/"

    To solve it, run
    heroku ps:scale web=1

  3. PUBLIC_URL
    In the package.json, I have :
    "homepage": "http://mywebsite.com/relativepath"
    It's for deploying to github some time I did and I just forgot it.
    That took me a while to figure out.


Saturday, February 13, 2021

heroku cheat sheets

 Login

heroku login

 

Logs

heroku logs -a [app name] --tail

heroku logs -app [app name] --tail 

Thursday, January 21, 2021

Query all images in gatsby

 The query is 

query MyQuery {
  allFile {
    edges {
      node {
        name
        ext
      }
    }
  }
}