Wednesday, March 24, 2021

Spelling numbers in Java in Crore, Lac and Thousand

Untitled
/*

1    crore  = 100  lac
1      lac  = 100  thousand
1 thousand  =  10  hundred

*/

public class SpellNumber{
        
        static long num;

        static final int DIGIT_LIMIT=20;

        static String spellNum[]=new String[100];
        static String tys[]=new String[10];

        static String positions[]=new String[DIGIT_LIMIT];
        static String scale[]={"","hundred","thousand1","thousand2", "lac1", "lac2", "crore1", "crore2"};

        static int digits[]=new int[DIGIT_LIMIT];



        static String spellDigits(int twoDgt){

            if(spellNum[twoDgt] != null) return spellNum[twoDgt];

            int firstDigit=twoDgt%10;
            twoDgt=twoDgt/10;
            int secondDigit=twoDgt;

            String out="";
            out=tys[secondDigit]+" ";
            out=out+spellNum[firstDigit];
            return out;
        }

    public static void main(String[] args) {

for(;;){

    System.out.println("Please input a decimal number(0 to exit):");
    num=new java.util.Scanner(System.in).nextLong();
    if(num==0) {
            System.out.println("Zero. Exiting...");
            break;
            }

        positions[1]=".1";
        positions[2]=".2";

        int scaleIndex=1;
        for(int i=3;i<DIGIT_LIMIT;i++){
        positions[i]=scale[scaleIndex];
        scaleIndex=scaleIndex%7+1;
        }

        spellNum[1]="One";
        spellNum[2]="Two";
        spellNum[3]="Three";
        spellNum[4]="Four";
        spellNum[5]="Five";
        spellNum[6]="Six";
        spellNum[7]="Seven";
        spellNum[8]="Eight";
        spellNum[9]="Nine";
        spellNum[10]="Ten";
        spellNum[11]="Eleven";
        spellNum[12]="Twelve";
        spellNum[13]="Thirteen";
        spellNum[14]="Forteen";
        spellNum[15]="Fifteen";
        spellNum[16]="Sixteen";
        spellNum[17]="Seventeen";
        spellNum[18]="Eighteen";
        spellNum[19]="Nineteen";
        spellNum[20]="Twenty";

        spellNum[30]="Thirty";
        spellNum[40]="Forty";
        spellNum[50]="Fifty";
        spellNum[60]="Sixty";
        spellNum[70]="Seventy";
        spellNum[80]="Eighty";
        spellNum[90]="Ninety";

        tys[2]="Twenty";
        tys[3]="Thirty";
        tys[4]="Forty";
        tys[5]="Fifty";
        tys[6]="Sixty";
        tys[7]="Seventy";
        tys[8]="Eighty";
        tys[9]="Ninety";

        long tmpNum=num;
        int count=1;

        for(;tmpNum!=0;){
            digits[count]=(int)tmpNum%10;
            tmpNum=tmpNum/10;

            count=count+1;
        }

        count--;

        int outDigits[]=new int[DIGIT_LIMIT];
        String outScales[]=new String[DIGIT_LIMIT];

        int outDigitCount=0;
        int outScaleCount=0;
        int bufferDigit=0;
        String bufferScale;

        for(int i=count;i>0;i--){

            switch(positions[i]){
                case "hundred":
                    outDigits[outDigitCount++]=digits[i];
                    outScales[outScaleCount++]="Hundred";
                    break;
                case "crore2":
                    bufferDigit=digits[i];bufferScale="Crore";
                    break;
                case "crore1":
                    outDigits[outDigitCount++]=bufferDigit*10+digits[i];
                    outScales[outScaleCount++]="Crore";
                    bufferDigit=0;bufferScale=null;
                    break;
                case "lac2":
                    bufferDigit=digits[i];bufferScale="Lac";
                    break;
                case "lac1":
                    outDigits[outDigitCount++]=bufferDigit*10+digits[i];
                    outScales[outScaleCount++]="Lac";
                    bufferDigit=0;bufferScale=null;
                    break;   
                case "thousand2":
                    bufferDigit=digits[i];bufferScale="Thousand";
                    break;
                case "thousand1":
                    outDigits[outDigitCount++]=bufferDigit*10+digits[i];
                    outScales[outScaleCount++]="Thousand";
                    bufferDigit=0;bufferScale=null;
                    break;
                default:

            }

        }

        String result="";
        String lastScale=null;
        String ranks="Hundred Thousand Lac Crore";

        for(int i=0;i<outDigitCount;i++){
            
            if(outDigits[i]==0 && lastScale != null) {

                if(ranks.indexOf(outScales[i]) > ranks.indexOf(lastScale))
                result=result+outScales[i]+" ";

                lastScale=outScales[i];
                continue;
            }

            if(outDigits[i]==0 && lastScale == null) {
                result=result+outScales[i]+" ";
                lastScale=outScales[i];
                continue;
            }

            if(outDigits[i]!=0) {
                result=result+spellDigits(outDigits[i])+" ";
                result=result+outScales[i]+" ";
                lastScale=outScales[i];
            }
        }

        if(digits[2]*10+digits[1] != 0)
        result=result+spellDigits(digits[2]*10+digits[1]);

        System.out.println(result);

}
    }

}
 
 

Friday, March 20, 2020

Adding new SSD and merging into existing logical volume in LVM without restarting Ubuntu 18.04/19.04

Untitled

So, getting newly added SSD simply merge into system and increase logical system storage space can be done configuring LVM on Ubuntu:

Following installing new SSD into laptop, run following command to list:

Should give:



Disk /dev/sda: 119.2 GiB, 128035676160 bytes, 250069680 sectors
Disk model: MTFDDAK128MAM-1J
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xf272f09b

Disk /dev/mapper/ubuntu--vg-root: 119.2 GiB, 628344487936 bytes, 1227235328 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/sdc: 477 GiB, 512110190592 bytes, 1000215216 sectors
Disk model: SanDisk SD6SB2M-
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xcbfa1baf

So, I have one 128GB SSD (/dev/sda) and a newly added 512GB SSD(/dev/sdc) in my system.

Lets merge new SSD drive /dev/sdc into logical volume group ubuntu–vg-root which should merge new SSD and increase combined storage size in LVM by 512MB and should display one single logical drive increased volume size by new solid state drives size:

Following executing above should give one single increased merged logical volume. Verify by running:

which should now give:


...
Disk /dev/mapper/ubuntu--vg-root: 585.2 GiB, 628344487936 bytes, 1227235328 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
...

which indicates our overall system storage size of root volume group ubuntu–vg-root size has been increased by newly added SSDs size (512MB).

Thursday, December 12, 2019

Getting started with Android development with React Native without an IDE

Untitled

PC checklist:

  • install android SDK
  • install android build tools ( for building from the command line ) and set PATH variables
  • install nodejs 12(>= recommended)

ANDROID device checklist:

  • enable developer mode
  • enable usb debugging within developer mode
  • connect your android phone to laptop and tap allow on your phone

On PC:

Install React Native:

npm install react react-native yarn

Install React Native CLI

npm install react-natice-cli -g

Create new project:

react-native init myproject

Setting project package name:

npm install react-native-rename -g react-native-rename “myproject” -b com.mycompany.myapp

This is at the moment a workaround, because of issue: https://github.com/facebook/react-native/issues/12721. Future releases are suppossed to support --package

Clean / Build project:

react-native run-android –tasks clean

Build:

react-native run-android –tasks build

Installing app on connected android device and starting up the app:

react-native run-android –tasks installRelease

Project structure:

  • App.js
  • index.js
  • app.json
  • babel.config.js
  • android/…
  • ios/…
  • __tests__/App-test.js
  • package.json

Seeing logs:

Or:

adb logcat|grep React

–

Sample logs for putting:

in App.js:

App.js:

Output logs:

09-16 16:10:41.813 28599 28616 D ReactNative: Initializing React Xplat Bridge after initializeBridge
09-16 16:10:41.814 28599 28616 D ReactNative: CatalystInstanceImpl.runJSBundle()
09-16 16:10:41.840 28599 28621 D ReactNative: ReactInstanceManager.setupReactContext()
09-16 16:10:41.840 28599 28621 D ReactNative: CatalystInstanceImpl.initialize()
09-16 16:10:41.845 28599 28621 D ReactNative: ReactInstanceManager.attachRootViewToInstance()
09-16 16:10:42.166 28599 28620 I ReactNativeJS: #####Hi
09-16 16:10:42.206 28599 28620 I ReactNativeJS: Running application “MyTestProject” with appParams: {“rootTag”:1}. DEV === false, development-level warning are OFF, performance optimizations

Unit Testing:

React Native preconfigures Jest for unit testing. Running:

yarn test

should give:


yarn run v1.12.3
$ jest
 PASS  __tests__/App-test.js (10.046s)
  ✓ renders correctly (7236ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        11.149s
Ran all test suites.
Done in 12.92s. 

Lets put some unit tests in __tests__/App-test.js:

Next yarn test should give us:


yarn run v1.12.3
$ jest
 PASS  __tests__/App-test.js
  ✓ adds 4 + 5 to equal 9 (3ms)
  ✓ renders correctly (377ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.555s
Ran all test suites.
Done in 2.27s.

Debugging App Crashes / App sudden stop:

For facing REs start Metro JS bundler and run app on debug mode. Simply run react-native start on a new terminal window. Or running this in current terminal should start up a new window running Metro:

now run:

This should start app up in debug mode:

Now saving any changes on App.js should refresh android app istance window instantly running on device while designing UI. And any exception messages whould should right appear on app window.

Monday, April 02, 2018

Spring Security + Hibernate : Enabling database login via Annotations

Hibernate Entities:

Employee.java
===========
package com.mycompany.myapp.entity;

import javax.persistence.*;
import java.util.*;

@Entity
@Table(name = "employee")
public class Employee {

    private long id;
    private String username;
    private String password;

    @Column(name = "enabled", columnDefinition = "boolean default true",
     nullable = false)
    private Boolean enabled = true;

    @Id
    @GeneratedValue
    @Column(name = "id")
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

//...

//other getters, setters

}

EmployeeRoles.java:
============
package com.mycompany.myapp.entity;

import javax.persistence.*;


@Entity
@Table(name = "employee_roles")
public class EmployeeRoles{

 private int id;
 private String employeeCode;
 private String role;

 @Id
 @GeneratedValue
 @Column(name = "id")
 public int getId()
 {

     return id;

 }

 
 public void setId(int id)
 {

     this.id = id;

 }

//other getters, setters
}

Initial Roles:

src/main/resources/import.sql:
====================================
insert into employee_roles(employee_code,role) 
values('SOME_EMPLOYEE_CODE','ROLE_USER');

Spring Security config:

WebSecurityConfig.java:
===================
package com.mycompany.myapp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication
.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders
.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration
.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configuration
.EnableWebSecurity;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation
.ResourceHandlerRegistry;
import javax.sql.*;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/webjars/**","/webjars/","/img/**",
                 "/styles/**","/js/**","/api/1.0/get**", "/about.html")
                 .permitAll().anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
                
    }


    @Autowired
    DataSource dataSource;
    
    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) 
throws Exception {
         
            auth.jdbcAuthentication().dataSource(dataSource)
       .usersByUsernameQuery(
          "select username,password, enabled 
                           from employee where username=?")
         .authoritiesByUsernameQuery(
            "select employee_code, role 
                        from employee_roles where employee_code=?");
    }
}

Saturday, March 24, 2018

Configuring legacy Cisco UCS C240 M3 v2 server power restore policy for automatic startup on power restore

Untitled

Server automatic start-up policy on power on/restore may come useful incase office building suffers temporary frequent power outages:

Setting up CIMC:

Restart and during server startup press F8 and it should bring up BIOS CIMC(Cisco Integrated Management Console):

  • Set NIC mode = Dedicated
  • Set NIC redundancy = None
  • Uncheck IPv6 and DHCP**
  • Set CIMC IP ( different from server IP ),subnet mask ( usually same as server ) and gateway ( usually same as server )
  • Set default user password for user ‘admin’
  • Press F10 to save configuration
  • Restart server.

Locating CIMC port:

At this point you have only provided all must have configurations for CIMC to be accesed. While browsing through server BIOS I could not find an option like ‘Power On on Power Restore’. I was struggling to find an answer on serverfault.com. Credit goes to Rob who introduced me to all these CIMC stuffs [ Thank you Rob :) ].

So, what is CIMC:

CIMC is a system management chip seperate from BIOS which runs an SSH service + an HTTP service independent of operating system. Many servers include a dedicated ethernet port for accessing CIMC. Our next job would be:

  • Locate CIMC port on server ( it should be an ethernet port marked ‘M’ on the back of the server ).
  • Connect server CIMC port to server switch via a CAT6 ethernet cable.

At this point we are finished our setup & are ready to access CIMC. CIMC can be accessed from any machine within local network via browser(http) or terminal(ssh).

Accessing CIMC through browser:

  • In case of Google Chrome, fire up a new browser tab and open http://CIMC_IP/
  • Chrome should warn unsafe connection. Click Advanced and Proceed Anyway.
  • Chrome may ask permission for running Flash. Click Allow.
  • At this point we should be redirected to a login page. Specify username ( default is admin ) & password.
  • For setting power policies click Power Policies and set Power Restore Policy* to Power On**.
  • Set Power Delay Type = fixed
  • Set Power Delay Value = 120 ( Warning: delay must be set to some suitable value like 1 or 2 minutes (e.g. 120 seconds). It takes some time for server itself to get completely ready, before executing ‘Power On’ event upon power restore. In our case ‘Power On’ did not work because we had set it 0 or 5/6 seconds. Setting 120 seconds delay solved it. )

Accessing CIMC through ssh:

Google Chrome will terminate flash support following December 2020. So, lets stick to ssh: * Fire up a new terminal window and type in following command, and run:

ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 admin@CIMC_IP

We need diffie-hellman-group1-sha1 because legacy Cisco devices offer old diffie-hellman-group1-sha1 as a key exchange algorithms.

Run following commands:

Note that you have to commit every changes to persist them in server config.

References:

https://www.cisco.com/c/en/us/td/docs/unified_computing/ucs/c/sw/gui/config/guide/1-0_1x/b_Cisco_UCS_C-Series_Servers_Integrated_Management_Controller_Configuration_Guide_1-0_1x.pdf
https://vinf.net/2014/09/18/press-f8-to-enter-cimc-configuration-does-not-work-on-cisco-c-class-rack-mount-server/ https://www.cisco.com/c/en/us/td/docs/unified_computing/ucs/c/sw/cli/config/guide/4_0/b_Cisco_UCS_C-Series_CLI_Configuration_Guide_40/b_Cisco_UCS_C-Series_CLI_Configuration_Guide_40_chapter_011.html