Tuesday, February 27, 2018

HackerRank - Grading Students Problem

This is a HackerRank Problem. You can find it HERE

Question

At HackerLand University, a passing grade is any grade 40 points or higher on a 100 point scale. Sam is a professor at the university and likes to round each student’s grade according to the following rules:
  • If the difference between the grade and the next higher multiple of 5 is less than 3, round to the next higher multiple of 5
  • If the grade is less than 38, don’t bother as it’s still a failing grade
Automate the rounding process then round a list of grades and print the results. ... Get details HERE

Solution


import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

    static int[] solve(int[] grades){
        int[] result = new int[grades.length];
        for (int i = 0; i < grades.length; i++) {
            if (grades[i] < 38) {
                result[i] = grades[i];
            } else {
                int rem = grades[i] % 5;
                if (rem < 3) {
                    result[i] = grades[i];
                } else {
                    result[i] = grades[i] + 5 - rem;
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] grades = new int[n];
        for(int grades_i=0; grades_i < n; grades_i++){
            grades[grades_i] = in.nextInt();
        }
        int[] result = solve(grades);
        for (int i = 0; i < result.length; i++) {
            System.out.print(result[i] + (i != result.length - 1 ? "\n" : ""));
        }
        System.out.println("");
    }
}








Tuesday, February 20, 2018

Intellij IDEA Shortcuts

Show Implementing Classes

To see all the classes which implement an interface, place your cursor on the interface name and push Ctrl+Alt+B. This will show all the classes implementing the interface.

See All Methods in Current Class

Press F12 to see all the methods in current class.

Go to Line Number

Press Ctrl+G. A dialog will pop up. Enter your line number to go to that line. You can also give column number after : to jump to that column of the line number.

Move Lines

Place cursor in the line which you want to move. Then press Shift+Alt+Up Arrow or Down Arrow to move the line up or down. To move multiple lines at once, select multiple lines before pressing the key combinations.

Delete Lines

Place cursor in the line which you want to delete. Then press Ctrl+y to delete the line. To delete multiple lines at once, select multiple lines before pressing the key combinations.

Duplicate Lines

Place cursor in the line which you want to duplicate. Then press Ctrl+d to duplicate the line. To duplicate multiple lines at once, select multiple lines before pressing the key combinations.






Monday, December 18, 2017

Google App Engine Devserver Exception Due to FormatStyle Restricted Class

In one of my application in Google App Engine, I tried to integrated Spring MVC.

The Spring version I used was 4.0.13.

Unfortunately, after the integration, it started to throw series of Exceptions following type one after another.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0': Initialization of bean failed [...]

nested exception is java.lang.NoClassDefFoundError: java.time.format.FormatStyle is a restricted class. Please see the Google App Engine developer's guide for more details.

Problem and Solution

The problem was, I had been using Java 8. With the integration of Spring, Spring Libraries try to use some of the classes which are restricted in App Engine (why?). So if I downgrade Java 1.8 to 1.7 then the problem will be fixed. However this cannot be the solution as anyone wants to use the latest version of Java.

The actual problem is, even though I had been using Java 8, App Engine's target JRE was still 1.7. So to fix this problem I had to add following snippet into appengine-web.xml:

<runtime>java8</runtime>








Monday, November 27, 2017

Java String.replaceAll() -- replace only the Matched String not the REGEX

Every Java programmer must have used the method,


String.replaceAll();


Usage Example


    "this is a test and that is another test".replaceAll("test", "rule");


the output of this execution will be:
"this is a rule and that is another rule"

Twist!!!

The usage of the method seems to be straightforward. However its not.

The first parameter to the method is actually a regular expression. You may fall into it, if the first argument has some special character which has different meaning in REGEX world.

What if you still want to match the expression as whole instead of as regex? You will need to convert it into String literal. You can do this by placing your expression in between Regex Quoted Literals. i.e. \Q <param> \E.


Example:


String test = "<span class=\"colorful\">This is a colorful text.</span>";
String replace_start = "<span class=\"colorful\">";
String replace_end = "</span>";

String expectedOutput = "This is a colorful text.";



Without Quoted Literals:


    String result = test.replace(replace_start, "").replace(replace_end, "");
    Assert.assertEquals(expectedOutput, result);

// This will fail because result = "<span class=\"colorful\">This is a colorful text.</span>"

With Quoted Literals


    String result = test.replace("\\Q" + replace_start + "\\E", "").replace("\\Q" + replace_end + "\\E", "");
    Assert.assertEquals(expectedOutput, result);

This will pass.







Tuesday, November 21, 2017

Get List of Links of All Shared Files From Your Dropbox (Using Java API)

Recently I had to extract the links of all the files shared in my dropbox.

Following was the first approach I used.

public List getLinks(DbxClientV2 client) throws DbxException {
    List result = new ArrayList();

    ListSharedLinksResult sharedLinksResult = client.sharing().listSharedLinks();
    for (SharedLinkMetadata slm : sharedLinksResult.getLinks()) {
      result.add(slm.getUrl());
    }

    return result;
  }

At first sight, this method seems to work perfectly fine. However, there is a glitch in the approach. The method

ListSharedLinksResult sharedLinksResult = client.sharing().listSharedLinks();

actually doesn't return all the result. It returns few items at a time. We can know whether there are more items or not by using

sharedLinksResult.getHasMore();
which returns True if there are more items left, False otherwise.

So if there are more items left, then we need to extract them as well.

sharedLinksResult has a cursor, which can be used to extract additional items. This can be done using:

client.sharing().listSharedLinks(new ListSharedLinksArg((String)null, sharedLinksResult.getCursor(), true));

But its not as easy as it looks. The problem is that the overloaded method listSharedLinks(ListSharedLinksArg) is not a Public Method. So you cannot you use just anywhere in your code.

Hack!!!

I managed to use this, by placing my class into the same package where the class DbxUserSharingRequests lie i.e. com.dropbox.core.v2. Obviously, this is not a clean approach.

Solution

As it turns out, the solution is to use

DbxUserSharingRequests.listSharedLinksBuilder()

where we can set the Cursor from sharedLinksResult. Following is my final solution:

public List getLinks(DbxClientV2 client) throws DbxException {
    List result = new ArrayList();

    ListSharedLinksResult sharedLinksResult = client.sharing().listSharedLinks();

    while(true) {
      for (SharedLinkMetadata slm : sharedLinksResult.getLinks()) {
        result.add(slm.getUrl());
      }

      if (sharedLinksResult.getHasMore()) {
        sharedLinksResult = client.sharing().listSharedLinksBuilder().withCursor(sharedLinksResult.getCursor()).withDirectOnly(true).start();
      } else {
        break;
      }
    }
    return result;
  }








Tuesday, July 18, 2017

Commonly Used Vi Vim Commands

REFERENCE: https://manandharsabbirk.appspot.com/articles/populate_article.html?id=mjdr45v1gsfwzyc/vi_common_commands.html

Show Line Numbers

:set number
This command is used to displaying line numbers in the editor.
:set nonumber
This is the counter command to the first numer. That is, this command will hide the line numbers.

Auto Indent

:autoindent
This command will auto indent the line as the previous line.
At any time, if you need to remove the indentation of the line you can press Ctrl+d.

Switching to New File

If you are working on a file in VIM and want to switch to a new file then you can use the following command:
:e    <file_name>

Split Screen

Sometimes we want to compare 2 files or the segments of same file. At such time, split feature of vim comes in handy. Screen can be easily split in vim. 

Split Screen Horizontally

:split
This code will split the screen horizontally. You can pass optional filename, if you want to open new file in the new window. If you don't pass any value, then the same file will be opened.

Split Screen Vertically

:vsplit
This code will split the screen vertically. Similar, to horizontal split, you can also pass a filename to open in the new window. 

Navigating the Splitted Screens

You can navigate the splitted screens by pressing Ctrl+w TWICE.
You can also do this by pressing Ctrl+w and then using the ARROW keys.

Close / Unsplit the Splitted Screens

CLICK HERE

Move to the End of Line

$

Move to the Last Line

:$

Move to a Line Number

:<line_number>
Note: :$ will move to last line.

Delete All

:1,$d

Copy/Paste Lines

yy
This command will copy the current line.
<number>yy
This command will copy <number> lines starting from the current line.
p
or
P
This command will paste the copied text.

Cut/Paste Lines

dd
This command will cut the current line.
<number>dd
This command will cut <number> lines starting from the current line.
p
or
P
This command will paste the copied text.

Copy/Cut Paste Selected Text

  1. Place the cursor to the position from where the text is to copied.
  2. Press v to begin the text selction.
  3. Move cursor to select the text.
  4. Press y to COPY or d to CUT the selected text.
  5. Press p or P to paste the text.

Insert Text (Spaces) in Multiple Lines at once

  1. Within VIM select block visual mode, by pressing CTRL-V .
  2. Use the cursor keys to select the lines you want to add the spaces to.
  3. Then enter :'<,'> norm I
  4. This will then insert a single space to the beginning of your select lines.
Lets break down the command :'<,'> norm I
  1. :'<,'> : For the line I selected
  2. norm : Execute the following sequence of keystrokes as if I was in normal mode
  3. I: Insert at the beginning of the line the following characters
  4. [space]: The character(s) you would like to insert







Wednesday, April 19, 2017

Generating Pagination Numbers

Very often we need to generate series of numbers for pagination. For small number of pages, all the page numbers can be displayed. However, when there are large number of pages, then we need to display only appropriate page numbers.

Below is a Java Code that can be used to generate the sequence.

It can be easily converted into Javascript function and make necessary changes as required to display in your web site.

public class Pagination {

     public static void main(String []args){
        generatePaginationNumbers(150, 5, 13);
     }
     
     public static void generatePaginationNumbers(int totalItems, int pageSize, int currentPage) {
         int DELTA = 3;
         int SHOW_ALL_SIZE = 10;
         int lastPage = totalItems/pageSize;
         if (totalItems > lastPage * pageSize) {
             lastPage++;
         }
         
         currentPage = currentPage < 1 ? 1 : currentPage;
         if (currentPage > lastPage) {
             currentPage = 1;
         }
         
         if (totalItems < 1) {
             return;
         }
         
         if (currentPage > 1) {
             System.out.print("prev ");
         }
         printPaginationPage(1, currentPage);
         if (totalItems > pageSize) {
             printPaginationPage(2, currentPage);
         } else {
             return;
         }
         
         if (currentPage - DELTA > 3 && lastPage > SHOW_ALL_SIZE) {
             System.out.print(" ... ");
         }
         
         int page = lastPage > SHOW_ALL_SIZE ? currentPage - DELTA : 3;
         page = page <= 2 ? 3 : page;
         int end = currentPage + DELTA;
         end = end >= lastPage - 1 ? lastPage - 2 : end;
         for( ; page <= end; page++) {
             printPaginationPage(page, currentPage);
         }
         
         if (page <= lastPage - 2 && lastPage > SHOW_ALL_SIZE) {
             System.out.print(" ... ");
         }
         
         printPaginationPage(lastPage - 1, currentPage);
         printPaginationPage(lastPage, currentPage);
         
         if (currentPage < lastPage) {
             System.out.print("next");
         }
     }
     
     public static void printPaginationPage(int page, int current) {
         if (page == current) {
             System.out.print("[" + page + "] ");
         } else {
             System.out.print(page + " ");
         }
     }
}


Sample Inputs and Outputs


generatePaginationNumbers(150, 5, 13);
Output: prev 1 2  ... 10 11 12 [13] 14 15 16  ... 29 30 next

generatePaginationNumbers(150, 5, 28);
Output: prev 1 2  ... 25 26 27 [28] 29 30 next

generatePaginationNumbers(150, 5, 2);
Output: prev 1 [2] 3 4 5  ... 29 30 next

generatePaginationNumbers(150, 5, 1);
Output: [1] 2 3 4  ... 29 30 next

generatePaginationNumbers(150, 5, 30);
Output: prev 1 2  ... 27 28 29 [30]