My First Post      My Facebook Profile      My MeOnShow Profile      W3LC Facebook Page      Learners Consortium Group      Job Portal      Shopping @Yeyhi.com









Friday, July 10, 2020

CSV delimiter linux Vs Mac : Resolving the issue of comma separated file read and write

Excel allows CSV that is Comma Separated Values in its filesystem. It uses comma as a delimiter.
And, this format is often used for exchanging data between programs. But there comes issues while working on different operating systems.


As per my research, there could be three versions of CSV formats included with Excel:


  • CSV (Comma delimited) (*.csv)
  • CSV (Macintosh) (*.csv)
  • CSV (MS-DOS) (*.csv)
The main difference arises because on a Macintosh each record (each line in the file) is terminated with a carriage return, as expected by the Mac. In the Windows, lines are terminated with a carriage return and line feed combination (CRLF). This can mess things up on the Macintosh.


Example suppose you are using Python for CSV Reader or writer mechanism then you should take care of two points:

1. use wb mode in file processing.

https://docs.python.org/2/library/csv.html#csv.writer


If csvfile is a file object, it must be opened with the ‘b’ flag on platforms where that makes a difference.

That is,  where you are writing file, open in binary format - wb mode
And, when reading - use rb mode

2. Use proper line separator. Better to use os.linesep



Even in viewing file also, you can do the difference if it is only a one time change:


Open your csv file with WPS Spreadsheets

Select the A column -> Data -> Text to Columns -> Next -> Select or define your delimiter -> Finish


You can also view a related post:

Cheers ;)

By the way I quit smoking. Did you know?

Line ending difference - Windows vs Linux Mac : Line Breaks \n CRLF explained and resolutions in Python, Java, Javascript, C++, Node.JS etc


The Windows environment and the UNIX environment use different end of line characters.  So, if you are sharing files between the environments, one of the environments sees end of line characters at the end of each line of text that it does not normally expect, while the other may give error.

In general, z/OS UNIX text files contain a newline character at the end of each line. In ASCII, newline is X'0A'. In EBCDIC, newline is X'15'. (For example, ASCII code page ISO8859-1 and EBCDIC code page IBM-1047 translate back and forth between these characters.) Windows programs normally use a carriage return followed by a line feed character at the end of each line of a text file. In ASCII, carriage return/line feed is X'0D'/X'0A'. In EBCDIC, carriage return/line feed is X'0D'/X'15'.



As per my research, when you give a Line break there are different behaviours or interpretation based on the platform you are using:


  • Windows: '\r\n'
  • Mac (OS 9-): '\r'
  • Mac (OS 10+): '\n'
  • Unix/Linux: '\n'


Resolution:

Identify in the program which operating system you are using. From there find the Line separator value. Following are the methods you can use for some different programming languages you would use:


Python:

import os
os.linesep

Java:

System.lineSeparator()

NodeJS:

require('os').EOL

C++:

Many methods including Boost Library
One method QDir::separator().toAscii()

C#

string eol = Environment.NewLine;


Cheers :)

Tuesday, June 30, 2020

Fix Why Spring boot @Autowired field null


Recently, I ran into a small issue and found the following article to be very helpful.
Suppose, you have a Spring @Service class (MileageFeeCalculator) that has an @Autowired field (rateService), but the field is null when I try to use it. The logs show that both the MileageFeeCalculator bean and the MileageRateService bean are being created, but I get a NullPointerException whenever I try to call the mileageCharge method on my service bean. Why isn't Spring autowiring the field?
Controller class:
@Controller
public class MileageFeeController {    
    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        MileageFeeCalculator calc = new MileageFeeCalculator();
        return calc.mileageCharge(miles);
    }
}
Service class:
@Service
public class MileageFeeCalculator {

    @Autowired
    private MileageRateService rateService; // <--- autowired="" be="" is="" null="" should="" span="">

    public float mileageCharge(final int miles) {
        return (miles * rateService.ratePerMile()); // <--- npe="" span="" throws="">
    }
}
Service bean that should be autowired in MileageFeeCalculator but it isn't:
@Service
public class MileageRateService {
    public float ratePerMile() {
        return 0.565f;
    }
}
The field annotated @Autowired is null because Spring doesn't know about the copy of MileageFeeCalculator that you created with new and didn't know to autowire it.
The Spring Inversion of Control (IoC) container has three main logical components: a registry (called the ApplicationContext) of components (beans) that are available to be used by the application, a configurer system that injects objects' dependencies into them by matching up the dependencies with beans in the context, and a dependency solver that can look at a configuration of many different beans and determine how to instantiate and configure them in the necessary order.
The IoC container isn't magic, and it has no way of knowing about Java objects unless you somehow inform it of them. When you call new, the JVM instantiates a copy of the new object and hands it straight to you--it never goes through the configuration process. There are three ways that you can get your beans configured.

Inject your beans

The most preferable option is to let Spring autowire all of your beans; this requires the least amount of code and is the most maintainable. To make the autowiring work like you wanted, also autowire the MileageFeeCalculator like this:
@Controller
public class MileageFeeController {

    @Autowired
    private MileageFeeCalculator calc;

    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        return calc.mileageCharge(miles);
    }
}
If you need to create a new instance of your service object for different requests, you can still use injection by using the Spring bean scopes.
Tag that works by injecting the @MileageFeeCalculator service object: working-inject-bean

Use @Configurable

If you really need objects created with new to be autowired, you can use the Spring @Configurable annotation along with AspectJ compile-time weaving to inject your objects. This approach inserts code into your object's constructor that alerts Spring that it's being created so that Spring can configure the new instance. This requires a bit of configuration in your build (such as compiling with ajc) and turning on Spring's runtime configuration handlers (@EnableSpringConfigured with the JavaConfig syntax). This approach is used by the Roo Active Record system to allow new instances of your entities to get the necessary persistence information injected.
@Service
@Configurable
public class MileageFeeCalculator {

    @Autowired
    private MileageRateService rateService;

    public float mileageCharge(final int miles) {
        return (miles * rateService.ratePerMile());
    }
}
Tag that works by using @Configurable on the service object: working-configurable

Manual bean lookup: not recommended

This approach is suitable only for interfacing with legacy code in special situations. It is nearly always preferable to create a singleton adapter class that Spring can autowire and the legacy code can call, but it is possible to directly ask the Spring application context for a bean.
To do this, you need a class to which Spring can give a reference to the ApplicationContext object:
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) 
throws BeansException {
        context = applicationContext;   
    }

    public static ApplicationContext getContext() {
        return context;
    }
}
Then your legacy code can call getContext() and retrieve the beans it needs:
@Controller
public class MileageFeeController {    
    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        MileageFeeCalculator calc = ApplicationContextHolder.getContext()
.getBean(MileageFeeCalculator.class);
        return calc.mileageCharge(miles);
    }
}

The original thread appeared on StackOverflow: https://stackoverflow.com/questions/19896870/why-is-my-spring-autowired-field-null