Wednesday, September 14, 2022

Improved fetch for REST API communication

Problem Statement: fetch or Axios does not throw error in case of domain is not valid or API does not respond in timely manner (like 5 -8 seconds which is acceptable) fetch or Axios relies on timeout defined within Browsers which is too high (1 minute for Brave, 5 minutes for Chrome)

Solution: Here is the improvised fetch function which can be used to avoid endless delays. It simply returns an objects after defined timeout so you can show toast message or throw a popup to user. 

Approach is very easy and simple.

const fetcher = async (URL, timeout) => {
    console.log(URL, timeout);
    try {
        const controller = new AbortController();
        const id = setTimeout(() => controller.abort(), timeout);

        const response = await fetch(URL, {
            method: 'GET', // *GET, POST, PUT, DELETE, etc.
            // mode: 'cors', // no-cors, *cors, same-origin
            cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
            // credentials: 'same-origin', // include, *same-origin, omit
            headers: {
                'Content-Type': 'application/json'
                // 'Content-Type': 'application/x-www-form-urlencoded',
            },
            redirect: 'follow', // manual, *follow, error
            referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
            signal: controller.signal
            // body: JSON.stringify(data) // body data type must match "Content-Type" header
        })
        clearTimeout(id);
        return response.json(); // parses JSON response into native JavaScript objects
    } catch(err) {
        return { "error": "connection failure",err }
    }
}

export { fetcher }  

Friday, November 12, 2021

JavaScript useful Date related (week,month,quarter) functions

As we all seen JavaScript is the most preferred programming language of the Internet.

Here are someuseful functions to iterate through the weeks / months / quarters in your code using simple JS functions.

    const weekRange = (num) => {
        // num defintion: -1 is pevious week, likewise -2,-3 OR only 1, 2 for upcoming weeks.
        let mydate = new Date();
        let mydate2 = new Date();
        num = num * 7; // 7 days per week * counter
        let x = mydate.getDate() - mydate.getDay() + 1; // +1 to set the first day of the week as Monday
        mydate.setDate(x + num);
        mydate.setHours(0, 0, 0); // setting the 0,0,0 to cover entire week right from day one midnight
        mydate2.setDate(x + num + 5 + 1); // +6 to calculatethe Saturday EOD
        mydate2.setHours(23, 59, 0); // setting 23,59 tp cover last day of the week till midnight
        return [mydate, mydate2]; //return array to compare the window with
    };

    const monthName = [
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December",
    ];

    const browseMonths = (num) => {
        // pass number of months you wish to add or subtract.
        let DateObj = new Date();
        DateObj.setMonth(DateObj.getMonth() + num);
        return DateObj;
    };


    const browseQuarter = (num) => {
        // num is ctr passed to calculate the future or past months
        let DateObj = new Date();
        let qstart = new Date();
        let qend = new Date();
        let quarter = "";
        num = parseInt(num);

        if (num !== 0) {
            DateObj.setMonth(DateObj.getMonth() + num * 3);
        } else {
            DateObj.setMonth(DateObj.getMonth());
        }
        const month = parseInt(DateObj.getMonth());

        if (month >= 0 && month <= 2) {
            quarter = "Q1 " + DateObj.getFullYear();
            //console.log(DateObj.toDateString());
            qstart = new Date(DateObj);
            qend = new Date(DateObj);
            qstart.setMonth(0);
            qstart.setDate(1);
            qstart.setHours(0, 0, 0);
            qend.setMonth(2);
            qend.setDate(31);
            qend.setHours(23, 59, 0);
        } else if (month >= 3 && month <= 5) {
            quarter = "Q2 " + DateObj.getFullYear();
            //console.log(DateObj.toDateString());
            qstart = new Date(DateObj);
            qend = new Date(DateObj);
            qstart.setMonth(3);
            qstart.setDate(1);
            qstart.setHours(0, 0, 0);
            qend.setMonth(5);
            qend.setDate(30);
            qend.setHours(23, 59, 0);
        } else if (month >= 6 && month <= 8) {
            quarter = "Q3 " + DateObj.getFullYear();
            //console.log(DateObj.toDateString());
            qstart = new Date(DateObj);
            qend = new Date(DateObj);
            qstart.setMonth(6);
            qstart.setDate(1);
            qstart.setHours(0, 0, 0);
            qend.setMonth(8);
            qend.setDate(30);
            qend.setHours(23, 59, 0);
        } else if (month >= 9 && month <= 11) {
            quarter = "Q4 " + DateObj.getFullYear();
            //console.log(DateObj.toDateString());
            qstart = new Date(DateObj);
            qend = new Date(DateObj);
            qstart.setMonth(9);
            qstart.setDate(1);
            qstart.setHours(0, 0, 0);
            qend.setMonth(11);
            qend.setDate(31);
            qend.setHours(23, 59, 0);
        } else {
            quarter = "";
        }
        return [quarter, qstart, qend];
    };

Friday, February 5, 2021

GoLang - Concurrency - channels for queueing

 package main


import (
    "fmt"
    "os"
    "time"
)

func add(a, b float64float64 {
    return a + b
}

func pause(sec int) {
    for i := 0; i <= sec; i++ {
        fmt.Println(" tic tic ", i)
        time.Sleep(time.Second / 4)
    }
}

func onetoten() {
    for i := 1; i <= 10; i++ {
        fmt.Print(" ", i)
        time.Sleep(time.Second / 4)
    }
}

func backg(msg chan string) {
    for {
        // wait for order from main func
        fmt.Println("print from inside backg goroutine: ", <-msg)
        // got the message now do something
        onetoten()
        pause(5)
    }
    //fmt.Println("The End!")
}

func main() {
    //fmt.Println(add(2, 3))
    //go pause(5)
    var mystring string
    mychannel := make(chan string5)
    defer close(mychannel)
    mychannel <- "Initial value for channel"
    go backg(mychannel)

    for {
        fmt.Println("\r\n Enter Text:")
        fmt.Scanln(&mystring)
        fmt.Printf("%s", mystring)
        mychannel <- mystring
        if mystring == "q" {
            os.Exit(0)
        }
    }

}

GoLang - process multiple files concurrently

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "strconv"
    "strings"
)

func check(e error) {
    if e != nil {
        panic(e)
    }
}

func analyze(msg string) {
    var total float64
    var min float64
    var max float64
    var numlines float64
    total = 0
    numlines = 0
    max = 0
    min = 1000000000
    dat2 := make([]string200)
    // read the file
    daterr := ioutil.ReadFile(msg)
    check(err)
    dat2 = strings.Split(string(dat), "\r\n")
    // iterate through the text file
    for i := 0; i < len(dat2); i++ {
        //fmt.Println("inside for loop", i)
        if figerr := strconv.ParseFloat(dat2[i], 64); err == nil {
            //total + new value
            total = total + fig
            numlines = numlines + 1
            if min > fig {
                min = fig
            }
            if max < fig {
                max = fig
            }

            //fmt.Println(fig)
        } else {
            // print error if not parsed
            fmt.Println(err)
            break
        }
    }
    fmt.Println("Analysis of file:", msg)
    fmt.Println("Total is:", total)
    fmt.Println("Total figures:", numlines)
    fmt.Println("Average is:", total/numlines)
    fmt.Println("Max: ", max, "Min: ", min)
}

func main() {

    var mystring string
    myslice := make([]string3)

    myslice[0] = "random_numbers1.txt"
    myslice[1] = "random_numbers2.txt"
    myslice[2] = "random_numbers3.txt"

    for i := 0; i < len(myslice); i++ {
        // trigger analyze as go routine
        // no need to use channels as we dont need to Queue anything
        go analyze(myslice[i])
    }

    for {
        fmt.Println("\r\n Enter Filename:")
        fmt.Scanln(&mystring)
        fmt.Printf("%s", mystring)
        if mystring == "q" {
            os.Exit(0)
        } else {
            go analyze(mystring)
        }

    }

}

GoLang - file analyze function

 package main


import (
    "fmt"
    "io/ioutil"
    "strconv"
    "strings"
)

func check(e error) {
    if e != nil {
        panic(e)
    }
}

func main() {
    var total float64
    var min float64
    var max float64
    var numlines float64
    total = 0
    numlines = 0
    max = 0
    min = 1000000000
    dat2 := make([]string200)
    // read the file
    daterr := ioutil.ReadFile("random_numbers1.txt")
    check(err)
    dat2 = strings.Split(string(dat), "\r\n")
    // iterate through the text file
    for i := 0; i < len(dat2); i++ {
        //fmt.Println("inside for loop", i)
        if figerr := strconv.ParseFloat(dat2[i], 64); err == nil {
            //total + new value
            total = total + fig
            numlines = numlines + 1
            if min > fig {
                min = fig
            }
            if max < fig {
                max = fig
            }

            //fmt.Println(fig)
        } else {
            // print error if not parsed
            fmt.Println(err)
        }
    }
    fmt.Println("Total is:", total)
    fmt.Println("Total fgures:", numlines)
    fmt.Println("Average is:", total/numlines)
    fmt.Println("Max: ", max, "Min: ", min)
}

Monday, August 17, 2020

Hotel & Waiter

हॉटेल आणि वेटर:



प्रस्तावना:

हॉटेलचे नाव हि जशी त्या जागेची ओळख असते तशी दुसरी ओळख तिथल्या वेटर मुळे मिळते. 

कितीही हॉटेल चांगले असेल आणि त्या वेटरने जेवण वाढताना जर चमचा तुमच्या मांडीत सांडवला कि सगळे मुसळ केरात. गॅरेंटी कि तुम्ही तिथे कधीही जाणार नाहीच. गम्मत आहे कि ह्यावर कधीही लिहिले जात नाही आणि आपण वेटर ना टीप देऊन विसरून सुद्धा जातो. वास्तविकतः जितका महत्वाचा शेफ असतो त्याहून कदाचित कमी का होईना पण थोडासा तरी महत्वाचा वेटर हा असतोच.  तो जबाबरदार असतो तुमच्या पूर्ण पुढच्या एक तासाच्या अनुभवा साठी 


chapter  १


माझा आज पर्यंतचा सर्वात आवडता वेटर असेल तो म्हणजे आराध्य , हा माणूस कर्नाटकी होता. ह्याला मराठी बोलता येत नव्हते पण तोडक्या मोडक्या हिंदी मध्ये बोलायचं पण चेहर्या वरील भाव नेहमी विनम्र. हा "हॉटेल रत्ना", (पिंपरी स्टेशन) मध्ये चाकरी करायचा.  हे हॉटेल थाळी आणि स्नॅक्स साठी प्रसिद्ध आहे. 

छोले भटुरे, डोसे , इडली, वडा हे उत्तम मिळते मिळते. पिंपरी वासियां साठी तर वरदान आहे हे हॉटेल म्हणजे . उगाच गाडी हाकत FC रोड वर जाऊन कोणी सांगितली वैशाली आणि वाडेश्वर मध्ये जायला , त्यापेक्षा ढेंगेवर असणाऱ्या रत्ना मध्ये जाऊन मस्त South Indian स्नॅक्स वर ताव मारायचा हा weekend चा ठरलेला बेत.  


हे आराध्य साहेब इथले कॅप्टन होते. आम्ही इथे प्रवेश केला की लगेच हजर आणि आम्ही जिथे बसू ते टेबले त्याच्या jurisdiction मधेच आहे असे दाखवत तो ताबा घेऊन टाकायचा. आम्ही विशेष तिखट खात नाही हे ह्याला अगदी चांगले माहित होते. त्यामुळे ऑर्डर दिली कि पुढे तिखट नको हे सांगायची गरज पडायची नाही. हे साहेब स्वतःच सांगून टाकायचे "आप फिकर मत करो, मै देख लुंगा" , म्हणजे आम्ही निश्चिन्त होऊन जेवण कधी येणार ह्याची वाट बघत बसायचे.


कधी कधी माझी मुलगी जी त्या वेळी ३ वर्षाची होती तिच्या साठी चेरी घेऊन ये, कधी रंगीत सरबत घेऊन ये ह्यामुळे तिची थोडीशी करमणूक वयाची. 

खरं तर हा काही कधी कुठल्या hotel management institute मध्ये न गेलेला पण त्याची शिस्त १ नंबर. कधीही कुठल्याही इतर वेटर वर आवाज चढवून बोलणार नाही पण वचक इतकी की त्याने सांगितले आणि ते झाले नाही २ मिनिटात असे होणार नाही.  


हळू हळू इतकं आराध्य आहे हे इतकं आंगवळणी पडलं कि आम्ही रत्ना मध्ये आराध्याचा पाहुणचार घ्यायला जातोय असेच वाटू लागले :)

एकदा हे साहेब गावी गेले होते दिवाळीच्या सुट्टी मध्ये तर त्याचं हजर नसणे अगदी प्रकर्षाने जाणवत होते. 


त्याच्या पुढील वेळेस गेलो तेव्हा परत आलेला होता आणि जरा हळवा वाटत होता. त्याने हळूच आवाजात सांगितले की मी पुढील आठवड्यात गावी जातो आहे आणि परत येणार नाही. वरचे वर हे पण सांगून गेला कि मी शेती साठी भांडवल जुळवायला आलो होतो आणि ते आता आहे म्हणून मी परत चाललो आहे.  मलाही थोडेसे वाईट वाटले पण त्याचे स्वप्न पूर्ण होते आहे ह्यातच सुख होते . आज त्याला भेटलेला १० वर्ष उलटून गेली पण अजूनही तो वल्ली लक्षात आहे. 


आता हे लिहून झाल्यावर मी माझा जुना नोकियाचा फोन चालू करून बघेन त्याचा नम्बर मिळेल का ते शोधेन , बघूया मी त्याला आठवतोय का ते :)


असो हा झाला chapter १. पुढील वल्ली आहे पंजाबी माणूस "केसर द ढाबा" मधील वजनदार रॉयल वेटर.  






Hotel Ratna, Pimpri: 
https://goo.gl/maps/tWDgLqQ1r9rVysL56


Sunday, July 12, 2020

Python - Number to Words

Program to convert Number to Words:

I am trying to teach Python to one of my old friend, and has given an assignment to convert numbers to words. So I tried doing it myself and It turned out to be fun.

I have used dictionary and recursive function :)

Code is readable so you may use logic in any language.


digitdict = {
  "0""",
  "1""One",
  "2""Two",
  "3""Three",
  "4""Four",
  "5""Five",
  "6""Six",
  "7""Seven",
  "8""Eight",
  "9""Nine",
}

tensdict = {
  "0""",
  "1""",
  "2""Twety",
  "3""Thirty",
  "4""Fourty",
  "5""Fifty",
  "6""Sixty",
  "7""Seventy",
  "8""Eighty",
  "9""Ninty",
}

exceptiondict = {
  "10""Ten",
  "11""Eleven",
  "12""Twelve",
  "13""Thirteen",
  "14""Fourteen",
  "15""Fifteen",
  "16""Sixteen",
  "17""Seventeen",
  "18""Eighteen",
  "19""Ninteen",
  "100""Hundred",
}


def num2words(mydigit):

    wordstring = ""

    if mydigit in exceptiondict:
        return exceptiondict[mydigit]

    if len(mydigit) == 1:
        wordstring = digitdict[mydigit]

    if len(mydigit) == 2:
        wordstring = tensdict[mydigit[0]]
        wordstring = wordstring + " " + digitdict[mydigit[1]]

    if len(mydigit) == 3:
        if int(mydigit) > 99:
            wordstring = digitdict[mydigit[0]] + wordstring + " Hundred " + num2words(mydigit[1:])
        else:
            wordstring = num2words(mydigit[1:])
    if len(mydigit) == 4:
        wordstring = digitdict[mydigit[0]] + " Thousand " + num2words(mydigit[1:])

    if len(mydigit) == 5:
        wordstring = num2words(mydigit[0:2]) + " Thousand " + num2words(mydigit[2:5])

    if len(mydigit) == 6:
        wordstring = num2words(mydigit[0:3]) + " Thousand " + num2words(mydigit[3:6])

    if len(mydigit) > 6:
        wordstring = "you are a millionnaire, give me some..."
    return wordstring

#prompt = "type a number:"
#mydigit = input(prompt)
#print(num2words(mydigit))

while 1 == 1:
    prompt = "Type a number(0 to quit):"
    mydigit = input(prompt.strip())
    if mydigit.isnumeric():
        if int(mydigit) == 0:
            print("Bye")
            exit(0)
        else:
            print(num2words(mydigit))
    else:
        print("not a number...")


#for i in range (21341,21400,1):
#    print(num2words(str(i)))