I would like to learn more about working/parsing with files and more generally with Strings.
So for that i created a custom .txt file with this input:
Function Time
print() 0:32
find() 0:40
insert() 1:34
I want to parse that file and to aggregate how much "functions" have been activated. Also, I want to aggregate the total time that it took for that (i.e., (0.32+0.4+1.34)/0.6 = 2:46 minutes)
For the above data, the output should be:
3 functions in total time of 2:46 minutes
For the solution, I obviously create BufferedReader and parse line by line, but there are lots of spaces, and I am not so great with working with that kind of input. I hope if someone can suggest me the proper way to work with that kind of data.
I will also appreciate any link to exercises of this kind since I am trying to get a job and they ask lots of questions about parsing this kind of data (strings and files).
Thanks for any help! :)
In general terms, you should process the file line by line. For each line, you can use the split function to split the line into several parts (from String to String[]). Notice that the argument of the split function is the character or the regular expression to use to split the original text. For instance, using str.split("\\s+") will split the input text treating multiple spaces as a single space. Also, you can use the trim function to erase unwanted spaces, end lines, tabs, etc. and then parse the information properly.
Concerning the specifics of parsing time values, Java has several built-in classes and methods to handle local dates, elapsed times, etc. (such as LocalTime or Calendar). However, in my example, I have built a custom FuncTime class to keep things easy.
Here is the code:
package fileParser;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class FileParser {
private static class FuncTime {
private int seconds;
private int minutes;
public FuncTime() {
this.seconds = 0;
this.minutes = 0;
}
public FuncTime(int seconds, int minutes) {
this.seconds = seconds;
this.minutes = minutes;
}
public void accumulate(FuncTime ft) {
this.seconds += ft.seconds;
while (this.seconds >= 60) {
this.seconds -= 60;
this.minutes += 1;
}
this.minutes += ft.minutes;
}
#Override
public String toString() {
return this.minutes + ":" + this.seconds;
}
}
private static void parseInfo(String fileName) {
// Create structure to store parsed data
Map<String, FuncTime> data = new HashMap<>();
// Parse data from file
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
// Skip header (DATA FILE MUST ALWAYS CONTAIN HEADER)
String line = reader.readLine();
// Begin to process from 2nd line
line = reader.readLine();
while (line != null) {
// Split funcName and time
String[] lineInfo = line.split("\\s+");
String funcName = lineInfo[0].trim();
// Split time in minutes and seconds
String[] timeInfo = lineInfo[1].split(":");
int seconds = Integer.valueOf(timeInfo[1].trim());
int minutes = Integer.valueOf(timeInfo[0].trim());
// Store the function name and its times
FuncTime ft = new FuncTime(seconds, minutes);
data.put(funcName, ft);
// Read next line
line = reader.readLine();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
// Print parsed information
FuncTime totalTime = new FuncTime();
for (Entry<String, FuncTime> entry : data.entrySet()) {
String funcName = entry.getKey();
FuncTime ft = entry.getValue();
System.out.println(funcName + " " + ft);
totalTime.accumulate(ft);
}
// Print total
System.out.println(data.size() + " functions in total time of " + totalTime);
}
public static void main(String[] args) {
String fileName = args[0];
parseInfo(fileName);
}
}
You can store the example data you provided in a file named example.data:
$ more example.data
Function Time
print() 0:32
find() 0:40
insert() 1:34
And run the above code obtaining the following output:
insert() 1:34
print() 0:32
find() 0:40
3 functions in total time of 2:46
You mean something like this?
int count = 0;
int totalMinutes = 0;
int totalSeconds = 0;
try (BufferedReader in = Files.newBufferedReader(Paths.get("test.txt"))) {
Pattern p = Pattern.compile("(\\S+)\\s+(\\d+):(\\d+)");
for (String line; (line = in.readLine()) != null; ) {
Matcher m = p.matcher(line);
if (m.matches()) {
// not used: String function = m.group(1);
int minutes = Integer.parseInt(m.group(2));
int seconds = Integer.parseInt(m.group(3));
count++;
totalMinutes += minutes;
totalSeconds += seconds;
}
}
}
if (count == 0) {
System.out.println("No functions found");
} else {
totalMinutes += totalSeconds / 60;
totalSeconds %= 60;
System.out.printf("%d functions in total time of %d minutes %d seconds%n",
count, totalMinutes, totalSeconds);
}
Output
3 functions in total time of 2 minutes 46 seconds
Related
I am in need of some guidance. I am not sure how to go about reading in the sample text file into an array of objects. I know that the work needs to be in the while loop I have in main. I just do not know what I need to accomplish this.
I understand that I need to read in the file line by line (that's what the while loop is doing), but I don't know how to parse that line into an object in my array.
I know all of you like to see what people have tried before you help, but I honestly don't know what to try. I don't need a hand out, just some guidance.
Sample Text File:
100 3
120 5
646 7
224 9
761 4
Main:
public static void main(String[] args) {
Weight[] arrWeights = new Weight[25];
int count = 0;
JFileChooser jfc = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
int returnValue = jfc.showOpenDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File selectedFile = jfc.getSelectedFile();
System.out.println(selectedFile.getAbsolutePath());
BufferedReader inputStream = null;
String fileLine;
inputStream = new BufferedReader(new FileReader(selectedFile.getAbsoluteFile()));
System.out.println("Weights:");
// Read one Line using BufferedReader
while ((fileLine = inputStream.readLine()) != null) {
count++;
System.out.println(fileLine);
}
System.out.println("Total entries: " + count);
}
}
Weight Class:
public class Weight {
private int pounds;
private double ounces;
private final int OUNCES_IN_POUNDS = 16;
public Weight(int pounds, double ounces) {
this.pounds = pounds;
this.ounces = ounces;
}
public boolean lessThan(Weight weight) {
return toOunces() < weight.toOunces();
}
public void addTo(Weight weight) {
this.ounces += weight.toOunces();
normalize();
}
public void divide(int divisor) {
if (divisor != 0) {
this.ounces = (this.toOunces() / divisor);
this.pounds = 0;
normalize();
}
}
public String toString() {
return this.pounds + " lbs " + String.format("%.3f", this.ounces) + " oz";
}
private double toOunces() {
return this.pounds * OUNCES_IN_POUNDS + this.ounces;
}
private void normalize() {
if (ounces >=16) {
this.pounds += (int) (this.ounces /OUNCES_IN_POUNDS);
this.ounces = this.ounces % OUNCES_IN_POUNDS;
}
}
}
I don't remember how to do that exactly in Java but I think this general guidance could help you:
In the while loop -
Parse the line you input from the read line using split function, you can use this as reference(first example can do the trick): http://pages.cs.wisc.edu/~hasti/cs302/examples/Parsing/parseString.html
Take the parsed line values, cast them to desired values per your class and create your object.
Append the created object to your list of objects: arrWeights
I am still relatively new to java but the problem that I am facing right now is that I keep getting a compile time error with what I currently have.
I'm not sure if there's a special logic structure that would take existing values from the file and convert the format of the numbers.
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import java.time.Duration;
public class Music {
// Method header
public static void main(String [] args) throws IOException{
// Variable declarations
String id;
String artistName;
String title;
String releaseName;
int year;
double endOfFadeIn;
double startOfFadeOut;
double loudness;
double duration;
// Scanner to read input from the user
Scanner keyboard = new Scanner(System.in);
// Scanner to read in the file that the user types.
System.out.print("Enter the name of the file: ");
String filename = keyboard.nextLine();
File inFile = new File(filename);
Scanner fileScan = new Scanner(inFile);
fileScan.useDelimiter(",|\\r?\\n");
fileScan.nextLine();
// Read from file using Scanner
while(fileScan.hasNext()) {
id = fileScan.next();
System.out.println(id);
id = formatID(id);
System.out.println(id);
artistName = fileScan.next();
System.out.println(artistName);
artistName = truncate(artistName);
title = fileScan.next();
System.out.println(title);
title = truncate(title);
releaseName = fileScan.next();
System.out.println(releaseName);
releaseName = truncate(releaseName);
year = fileScan.nextInt();
System.out.println(year);
endOfFadeIn = fileScan.nextDouble();
System.out.println(endOfFadeIn);
startOfFadeOut = fileScan.nextDouble();
System.out.println(startOfFadeOut);
loudness = fileScan.nextDouble();
System.out.println(loudness);
System.out.printf("%-10s %-20s %-20s %-20s%n", id, artistName, title,
releaseName);
}
}// end main
public static String formatID(String id) {
String newid;
newid = id.substring(0,7) + "-" + id.substring(7,9) + "-" + id.substring(9,18);
return newid;
}//end formatID
public static String truncate(String str){
if (str.length() > 20) {
return str.substring(0, 20-3) + "...";
} else {
return str;
}
}//end truncateStr
public static String formatTime(double duration) {
int days=0;
int hours=0;
int minutes=0;
int seconds=0;
String Result;
Result = System.out.printf("%03s:%02s:%02s:%02s", days, hours, minutes, seconds);
string.format
System.out.printf("%03s:%02s:%02s:%02s", days, hours, minutes, seconds);
duration = (int) duration;
duration = (startOfFadeOut - endOfFadeIn);
duration = Math.round(duration);
}//end formatTime
}//end class
The expected result is that when the values are read in from the file the output will display the time in this format DD:HH:MM:SS.
You didn't specify what the compile-time error was or which line of your code was causing it, but since you posted a MRE, I just needed to copy your code in order to discover what it was. It is this line:
String Result;
Result = System.out.printf("%03s:%02s:%02s:%02s", days, hours, minutes, seconds);
Method printf returns a PrintStream and not a String. If you want a String, use method format
So your code should be...
String Result;
Result = String.format("%03s:%02s:%02s:%02s", days, hours, minutes, seconds);
System.out.printf(Result);
Also, according to java coding conventions, variable names - like Result - should start with a lower-case letter, i.e. result.
You are given a list of file names and their lengths in bytes.
Example:
File1: 200 File2: 500 File3: 800
You are given a number N. We want to launch N threads to read all the files parallelly such that each thread approximately reads an equal amount of bytes
You should return N lists. Each list describes the work of one thread: Example, when N=2, there are two threads. In the above example, there is a total of 1500 bytes (200 + 500 + 800). A fairway to divide is for each thread to read 750 bytes. So you will return:
Two lists
List 1: File1: 0 - 199 File2: 0 - 499 File3: 0-49 ---------------- Total 750 bytes
List 2: File3: 50-799 -------------------- Total 750 bytes
Implement the following method
List<List<FileRange>> getSplits(List<File> files, int N)
Class File {
String filename; long length }
Class FileRange {
String filename Long startOffset Long endOffset }
I tried with this one but it's not working any help would be highly appreciated.
List<List<FileRange>> getSplits(List<File> files, int n) {
List<List<FileRange>> al=new ArrayList<>();
long s=files.size();
long sum=0;
for(int i=0;i<s;i++){
long l=files.get(i).length;
sum+=(long)l;
}
long div=(long)sum/n; // no of bytes per thread
long mod=(long)sum%n;
long[] lo=new long[(long)n];
for(long i=0;i<n;i++)
lo[i]=div;
if(mod!=0){
long i=0;
while(mod>0){
lo[i]+=1;
mod--;
i++;
}
}
long inOffset=0;
for(long j=0;j<n;j++){
long val=lo[i];
for(long i=0;i<(long)files.size();i++){
String ss=files.get(i).filename;
long ll=files.get(i).length;
if(ll<val){
inOffset=0;
val-=ll;
}
else{
inOffset=ll-val;
ll=val;
}
al.add(new ArrayList<>(new File(ss,inOffset,ll-1)));
}
}
}
I'm getting problem in startOffset and endOffset with it's corresponding file. I tried it but I was not able to extract from List and add in the form of required return type List>.
The essence of the problem is to simultaneously walk through two lists:
the input list, which is a list of files
the output list, which is a list of threads (where each thread has a list of ranges)
I find that the easiest approach to such problems is an infinite loop that looks something like this:
while (1)
{
move some information from the input to the output
decide whether to advance to the next input item
decide whether to advance to the next output item
if we've reached (the end of the input _OR_ the end of the output)
break
if we advanced to the next input item
prepare the next input item for processing
if we advanced to the next output item
prepare the next output item for processing
}
To keep track of the input, we need the following information
fileIndex the index into the list of files
fileOffset the offset of the first unassigned byte in the file, initially 0
fileRemain the number of bytes in the file that are unassigned, initially the file size
To keep track of the output, we need
threadIndex the index of the thread we're currently working on (which is the first index into the List<List<FileRange>> that the algorithm produces)
threadNeeds the number of bytes that the thread still needs, initially base or base+1
Side note: I'm using base as the minimum number bytes assigned to each thread (sum/n), and extra as the number of threads that get an extra byte (sum%n).
So now we get to the heart of the algorithm: what information to move from input to output:
if fileRemain is less than threadNeeds then the rest of the file (which may be the entire file) gets assigned to the current thread, and we move to the next file
if fileRemain is greater than threadNeeds then a portion of the file is assigned to the current thread, and we move to the next thread
if fileRemain is equal to threadNeeds then the rest of the file is assigned to the thread, and we move to the next file, and the next thread
Those three cases are easily handled by comparing fileRemain and threadNeeds, and choosing a byteCount that is the minimum of the two.
With all that in mind, here's some pseudo-code to help get you started:
base = sum/n;
extra = sum%n;
// initialize the input control variables
fileIndex = 0
fileOffset = 0
fileRemain = length of file 0
// initialize the output control variables
threadIndex = 0
threadNeeds = base
if (threadIndex < extra)
threadNeeds++
while (1)
{
// decide how many bytes can be assigned, and generate some output
byteCount = min(fileRemain, threadNeeds)
add (file.name, fileOffset, fileOffset+byteCount-1) to the list of ranges
// decide whether to advance to the next input and output items
threadNeeds -= byteCount
fileRemain -= byteCount
if (threadNeeds == 0)
threadIndex++
if (fileRemain == 0)
fileIndex++
// are we done yet?
if (threadIndex == n || fileIndex == files.size())
break
// if we've moved to the next input item, reinitialize the input control variables
if (fileRemain == 0)
{
fileOffset = 0
fileRemain = length of file
}
// if we've moved to the next output item, reinitialize the output control variables
if (threadNeeds == 0)
{
threadNeeds = base
if (threadIndex < extra)
threadNeeds++
}
}
Debugging tip: Reaching the end of the input, and the end of the output, should happen simultaneously. In other words, you should run out of files at exactly the same time as you run out of threads. So during development, I would check both conditions, and verify that they do, in fact, change at the same time.
Here's the code solution for your problem (in Java) :
The custom class 'File' and 'FileRange' are as follows :
public class File{
String filename;
long length;
public File(String filename, long length) {
this.filename = filename;
this.length = length;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public long getLength() {
return length;
}
public void setLength(long length) {
this.length = length;
}
}
public class FileRange {
String filename;
Long startOffset;
Long endOffset;
public FileRange(String filename, Long startOffset, Long endOffset) {
this.filename = filename;
this.startOffset = startOffset;
this.endOffset = endOffset;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public Long getStartOffset() {
return startOffset;
}
public void setStartOffset(Long startOffset) {
this.startOffset = startOffset;
}
public Long getEndOffset() {
return endOffset;
}
public void setEndOffset(Long endOffset) {
this.endOffset = endOffset;
}
}
The main class will be as follows :
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;
public class MainClass {
private static List<List<FileRange>> getSplits(List<File> files, int N) {
List<List<FileRange>> results = new ArrayList<>();
long sum = files.stream().mapToLong(File::getLength).sum(); // Total bytes in all the files
long div = sum/N;
long mod = sum%N;
// Storing how many bytes each thread gets to process
long thread_bytes[] = new long[N];
// At least 'div' number of bytes will be processed by each thread
for(int i=0;i<N;i++)
thread_bytes[i] = div;
// Left over bytes to be processed by each thread
for(int i=0;i<mod;i++)
thread_bytes[i] += 1;
int count = 0;
int len = files.size();
long processed_bytes[] = new long[len];
long temp = 0L;
int file_to_be_processed = 0;
while(count < N && sum > 0) {
temp = thread_bytes[count];
sum -= temp;
List<FileRange> internal = new ArrayList<>();
while (temp > 0) {
// Start from the file to be processed - Will be 0 in the first iteration
// Will be updated in the subsequent iterations
for(int j=file_to_be_processed;j<len && temp>0;j++){
File f = files.get(j);
if(f.getLength() - processed_bytes[j] <= temp){
internal.add(new FileRange(f.getFilename(), processed_bytes[j], f.getLength()- 1));
processed_bytes[j] = f.getLength() - processed_bytes[j];
temp -= processed_bytes[j];
file_to_be_processed++;
}
else{
internal.add(new FileRange(f.getFilename(), processed_bytes[j], processed_bytes[j] + temp - 1));
// In this case, we won't update the number for file to be processed
processed_bytes[j] += temp;
temp -= processed_bytes[j];
}
}
results.add(internal);
count++;
}
}
return results;
}
public static void main(String args[]){
Scanner scn = new Scanner(System.in);
int N = scn.nextInt();
// Inserting demo records in list
File f1 = new File("File 1",200);
File f2 = new File("File 2",500);
File f3 = new File("File 3",800);
List<File> files = new ArrayList<>();
files.add(f1);
files.add(f2);
files.add(f3);
List<List<FileRange>> results = getSplits(files, N);
final AtomicInteger result_count = new AtomicInteger();
// Displaying the results
results.forEach(result -> {
System.out.println("List "+result_count.incrementAndGet() + " : ");
result.forEach(res -> {
System.out.print(res.getFilename() + " : ");
System.out.print(res.getStartOffset() + " - ");
System.out.print(res.getEndOffset() + "\n");
});
System.out.println("---------------");
});
}
}
If some part is still unclear, consider a case and dry run the program.
Say 999 bytes have to be processed by 100 threads
So the 100 threads get 9 bytes each and out of the remaining 99 bytes, each thread except the 100th gets 1 byte. By doing this, we'll make sure no 2 threads differ by at most 1 byte. Proceed with this idea and follow up with the code.
I am developing java application using Eclipse for text recognition from image using Asprise Library. In my maven project POM.xml file I have included this dependencies
<dependency>
<groupId>com.asprise.ocr</groupId>
<artifactId>java-ocr-api</artifactId>
<version>15.3.0.3</version>
</dependency>
The important jar files has already been downloaded to my project as it can be seen in the given picture. If i try to make an Ocr object i am getting this error.
Ocr cannot be resolved.
I am new to maven in Eclipse. I have no idea what is wrong in this. My complete code is shown here
package com.asprise;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import com.asprise.ocr.Ocr;
public class AspriseOCR {
static long startTime;
static long EndTime;
static double tPeriod;
static double ElapsedTime;
private static double totalTime = 0;
private static double correctImgs = 0;
static double averageTime = 0;
static double strMatch;
static double accuracy = 0;
public static void main(String[] args) {
try {
Ocr.setUp();
Ocr ocr = new Ocr();
ocr.startEngine("eng", Ocr.SPEED_FASTEST);
String groundTruthLine = "";
BufferedReader br = new BufferedReader(new FileReader("F:\\ground_truth.txt"));
int numOfImges = 100;
for (int i=1; i <=numOfImges; i++ )
{
System.out.println("\t\t\timg( " + i + ") \t\t\t" );
groundTruthLine = br.readLine();
String path2 = "F:\\img (" + i + ").png";
startTime = System.currentTimeMillis();
String recognizedText = ocr.recognize(new File[] {new File(path2)},
Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
EndTime = System.currentTimeMillis();
tPeriod = EndTime - startTime;
ElapsedTime = tPeriod/1000.0;
matchString(groundTruthLine, recognizedText, ElapsedTime);
System.out.println();
System.out.println();
System.out.println("***************************************************************************");
}
br.close();
System.out.println("Average Time " + ElapsedTime/numOfImges);
System.out.println("Average Accuracy " + (accuracy/numOfImges));
ocr.stopEngine();
}catch(Exception e)
{
}
}
private static void matchString(String groundTruth, String result, double elapsedTime) {
String replacedText = result.replaceAll("\n", "");
int gTruthLenth = groundTruth.length();
int detectedText = replacedText.length();
if (detectedText > (gTruthLenth * 2)) {
replacedText = replacedText.substring(0, gTruthLenth * 2);
}
strMatch = StringMatchingViaEditDist(replacedText, groundTruth, replacedText.length(), groundTruth.length());
double imgAccuracy = ((groundTruth.length() - strMatch)/ groundTruth.length());
System.out.println("Ground Truth :: " + groundTruth);
System.out.println("Returned Text :: " + replacedText );
System.out.println("Match Found :: " + imgAccuracy);
totalTime += elapsedTime;
accuracy = accuracy + imgAccuracy;
}
private static int min(int x,int y,int z)
{
if (x<y && x<z) return x;
if (y<x && y<z) return y;
else return z;
}
static int StringMatchingViaEditDist(String str1 , String str2 , int m ,int n)
{
// If first string is empty, the only option is to
// insert all characters of second string into first
if (m == 0) return n;
// If second string is empty, the only option is to
// remove all characters of first string
if (n == 0) return m;
// If last characters of two strings are same, nothing
// much to do. Ignore last characters and get count for
// remaining strings.
if (str1.charAt(m-1) == str2.charAt(n-1))
return StringMatchingViaEditDist(str1, str2, m-1, n-1);
// If last characters are not same, consider all three
// operations on last character of first string, recursively
// compute minimum cost for all three operations and take
// minimum of three values.
return 1 + min ( StringMatchingViaEditDist(str1, str2, m, n-1), // Insert
StringMatchingViaEditDist(str1, str2, m-1, n), // Remove
StringMatchingViaEditDist(str1, str2, m-1, n-1) // Replace
);
}
}
I have an string array that includes some minutes like "00:05", "00:30", "00:25" etc. I want to sum the values as time format? Can anyone help me how do I do this?
Total time in minutes:
int sum = 0;
final String[] mins = new String[] { "00:05", "00:30", "00:25" };
for (String str : mins) {
String[] parts = str.split(":");
sum += Integer.parseInt(parts[1]);
}
System.out.println(sum);
You don't specify exactly how you want this output formatted.
If there may be hour elements as well, then replace the second line of the loop with this:
sum += (Integer.parseInt(parts[0]) * 60) + Integer.parseInt(parts[1]);
I'll go for quick and dirty
Split each String on the ":"
Convert both parts to integer
Multiply the first time by 60 to convert hours to minutes, and add the second part
Do this for each value in your array, and count them together
This results in the total time in minutes, which you can convert to whatever format you like
You could substring it, and then call Integer.parseInt on the result. For the hours part, do the same and multiply it by 60.
Split the strings on ':', pars the values as ints and add 'em up.
this is my suggestion. Neither compiled, ran, tested, nor guaranteed.
long seconds = 0;
for ( String min : minutes )
{
seconds += Integer.parseInt(min.substring(0,1))*60 + Integer.parseInt(min.substring(3,4));
}
return new Date ( seconds / 1000 ) ;
An object oriented approach:
public static TimeAcumm sum(final String[] times) {
final TimeAcumm c = new TimeAcumm();
for (final String time : times) {
c.incrementFromFormattedString(time);
}
return c;
}
public class TimeAcumm {
private int hours = 0;
private int minutes = 0;
private int seconds = 0;
public int getHours() {
return hours;
}
public int getMinutes() {
return minutes;
}
public int getSeconds() {
return seconds;
}
public void incrementFromFormattedString(final String time) {
final String[] parts = time.split(":");
this.minutes += Integer.parseInt(parts[0]);
this.seconds += Integer.parseInt(parts[1]);
validate();
}
private void validate() {
if (this.minutes > 59) {
this.hours++;
this.minutes -= 60;
}
if (this.seconds > 59) {
this.minutes++;
this.seconds -= 60;
}
}
#Override
public String toString() {
final String s = hours + "H:" + minutes + "M:" + seconds + "S";
return s;
}
}