LebGeeks

A community for technology geeks in Lebanon.

You are not logged in.

#1 December 27 2010

arithma
Member

Exercise - Text Processing and More

This company we're dealing with, that's handling our phone fees, is sending us some reports on our employees' personal calls. The bad part of the story is that their programmers are inept, and they couldn't do anything better than the pathological format they send the data in. The programmers are now dead (shot out of frustration by their boss), while the handling company doesn't have the resources to comprehend their existing code to update it to something more sane.

Enough introductions. The report should contain rows of the following fields:
- T: time (e.g. 10PM, 12AM, 1PM, 8PM)
- D: duration (e.g. 12sec, 894sec, 2000sec, ...)
- N: number (e.g. +71231888, +70929112, ..)
- Y: type (only one of these: SMS, WAP, PHONECALL)

The thing is, when the type is WAP, the phone number will not be included.

11PM
12PM
9AM
11AM
20sec
30sec
10sec
0sec
+70702211
+70703311
+70112111
PHONECALL
PHONECALL
WAP
SMS

This should be interpretted as:

T1
T2
T3
T4
D1
D2
D3
D4
N1
N2
N4
Y1
Y2
Y3
Y4

The purpose of this exercise is to reorganize the data so that it looks like this

T1 D1 N1 Y1
T2 D2 N2 Y2
T3 D3 N/A Y3
T4 D4 N4 Y4

Offline

#2 December 27 2010

MSD
Member

Re: Exercise - Text Processing and More

Sounds more like a job description than an exercise :)

Offline

#3 December 27 2010

arithma
Member

Re: Exercise - Text Processing and More

You're the newbie here, take your place. If you can check the profile history, you'd see I am posting these stuff like for a while now.

This is an insult, I can't take it lightly.

Offline

#4 December 27 2010

MSD
Member

Re: Exercise - Text Processing and More

Wow, pulling seniority on me!
Anyways, I was just saying that it "sounded" like a real case scenario. Moreover, we are not in the army, and you don't get to order me around.

Offline

#5 December 27 2010

arithma
Member

Re: Exercise - Text Processing and More

The newbie part is alluding to your ignorance to our practices (the exercises I am trying to resurrect), not to the fact that I am a senior here by any measure. It's just not really acceptable of you coming into a well practiced thing we do here and suggest insulting things like that.
We're not the army, but we do usually have a sense of respect for each other here, and some things are just unacceptable.

Offline

#6 December 27 2010

Padre
Member

Re: Exercise - Text Processing and More

lol arithma, take it easy :)
and MSD, read before you post. it might sound like one, but it's not. arithma wouldn't need much to finish the exercise.
Interesting exercise, pretty much straight forward tho.

Offline

#7 December 27 2010

MSD
Member

Re: Exercise - Text Processing and More

Forget I even said anything, don't wanna make a deal out of it.
So let's call the quarrel off, and here is a solution in case anyone is interested (C#):

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        private static List<string> _TimeList = new List<string>();
        private static List<string> _DurationList = new List<string>();
        private static List<string> _NumberList = new List<string>();
        private static List<string> _TypeList = new List<string>();
        private static string _Input =
@"11PM
12PM
9AM
11AM
20sec
30sec
10sec
0sec
+70702211
+70703311
+70112111
PHONECALL
PHONECALL
WAP
SMS";
        private static string ParseInput()
        {
            foreach (string s in _Input.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
            {
                if (s.EndsWith("PM") || s.EndsWith("AM"))
                    _TimeList.Add(s);
                else if (s.EndsWith("sec"))
                    _DurationList.Add(s);
                else if (s[0] == '+')
                    _NumberList.Add(s);
                else
                {
                    if (s == "WAP")
                        _NumberList.Insert(_TypeList.Count - 1, "N/A");
                    _TypeList.Add(s);
                }
            }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < _TypeList.Count; i++)
                sb.AppendFormat("{0}\t{1}\t{2}\t{3}\n", _TimeList[i], _DurationList[i], _NumberList[i], _TypeList[i]);
            return sb.ToString();
        }
        static void Main(string[] args)
        {
            Console.Write(ParseInput());
        }

    }
}

Offline

#8 December 27 2010

MSD
Member

Re: Exercise - Text Processing and More

Here is a more performant solution:

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        private static List<string> _TimeList = new List<string>();
        private static List<string> _DurationList = new List<string>();
        private static List<string> _NumberList = new List<string>();
        private static List<string> _TypeList = new List<string>();
        private static string _Input =
@"11PM
12PM
9AM
11AM
20sec
30sec
10sec
0sec
+70702211
+70703311
+70112111
PHONECALL
PHONECALL
WAP
SMS";

        private static string GetNextWord(string input, ref int index)
        {
            string buffer = string.Empty;
            while (index < input.Length && input[index] != '\r' && input[index] != '\n')
            {
                buffer += input[index++];
            }
            index++;
            if (index < input.Length && input[index] == '\n')
                index++;
            return buffer;
        }
        private static string ParseInput()
        {
            for (int index = 0; index < _Input.Length;)
            {
                string s = GetNextWord(_Input, ref index);
                if (s.EndsWith("PM") || s.EndsWith("AM"))
                    _TimeList.Add(s);
                else if (s.EndsWith("sec"))
                    _DurationList.Add(s);
                else if (s[0] == '+')
                    _NumberList.Add(s);
                else
                {
                    if (s == "WAP")
                        _NumberList.Insert(_TypeList.Count - 1, "N/A");
                    _TypeList.Add(s);
                }
            }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < _TypeList.Count; i++)
                sb.AppendFormat("{0}\t{1}\t{2}\t{3}\n", _TimeList[i], _DurationList[i], _NumberList[i], _TypeList[i]);
            return sb.ToString();
        }
        static void Main(string[] args)
        {
            Console.Write(ParseInput());
            Console.Read();
        }
    }
}

Offline

#9 December 27 2010

arithma
Member

Re: Exercise - Text Processing and More

@Padre: Don't worry I didn't get out of my temper. Thanks for the backing up :)
@MSD: We're very cool. Thanks for having interest in this exercise.
Though I'd like to warn to a common off-by-one error. The insert should have inserted into TypeList.Count.

Offline

#10 December 27 2010

MSD
Member

Re: Exercise - Text Processing and More

Yup, corrected:

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        private static List<string> _TimeList = new List<string>();
        private static List<string> _DurationList = new List<string>();
        private static List<string> _NumberList = new List<string>();
        private static List<string> _TypeList = new List<string>();
        private static string _Input =
@"11PM
12PM
9AM
11AM
20sec
30sec
10sec
0sec
+70702211
+70703311
+70112111
PHONECALL
PHONECALL
WAP
SMS";

        private static string GetNextWord(string input, ref int index)
        {
            string buffer = string.Empty;
            while (index < input.Length && input[index] != '\r' && input[index] != '\n')
            {
                buffer += input[index++];
            }
            index++;
            if (index < input.Length && input[index] == '\n')
                index++;
            return buffer;
        }
        private static string ParseInput()
        {
            for (int index = 0; index < _Input.Length;)
            {
                string s = GetNextWord(_Input, ref index);
                if (s.EndsWith("PM") || s.EndsWith("AM"))
                    _TimeList.Add(s);
                else if (s.EndsWith("sec"))
                    _DurationList.Add(s);
                else if (s[0] == '+')
                    _NumberList.Add(s);
                else
                {
                    if (s == "WAP")
                        _NumberList.Insert(_TypeList.Count, "N/A");
                    _TypeList.Add(s);
                }
            }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < _TypeList.Count; i++)
                sb.AppendFormat("{0}\t{1}\t{2}\t{3}\n", _TimeList[i], _DurationList[i], _NumberList[i], _TypeList[i]);
            return sb.ToString();
        }
        static void Main(string[] args)
        {
            Console.Write(ParseInput());
            Console.Read();
        }
    }
}

Offline

#11 December 28 2010

Joe
Member

Re: Exercise - Text Processing and More

#!/usr/bin/python

class PlanHandler:

    TList = []
    DList = []
    NList = []
    YList = []
    plan = []

    def __init__(self, filename):
        f = open('input', 'r')
        for line in f:
            if line.find("AM") != -1: 
                self.TList.append(line)
            elif line.find("PM") != -1: 
                self.TList.append(line)
            elif line.find("+") != -1: 
                self.NList.append(line)
            elif line.find("sec") != -1: 
                self.DList.append(line)
            elif line.find("WAP") != -1: 
                self.YList.append(line)
                self.NList.insert(len(self.YList) - 1, "N/A")
            else:
                self.YList.append(line)
        f.close()    

    def populatePlan(self):
        index = 0 
        while index < len(self.TList):
            o = Conversation (self.TList[index], self.DList[index], self.NList[index], self.YList[index])
            self.plan.append(o)
            index += 1

    def prettyPrint(self, separator):
        for p in self.plan:
            p.prettyPrint(separator)


class Conversation:

    def __init__(self, time, duration, number, _type):
        self.time = time
        self.duration = duration
        self.number = number
        self._type = _type

    def prettyPrint(self, separator):
        f = open("output", "a")
        f.write(self.time + separator + self.duration + separator + self.number + separator + self._type + separator)
        f.close()


def main():
    p = PlanHandler('input')
    p.populatePlan()
    p.prettyPrint(" ")


if __name__ == '__main__':
    main()

Offline

#12 December 28 2010

rolf
Member

Re: Exercise - Text Processing and More

<?php

$input = "
11PM
12PM
9AM
11AM
20sec
30sec
10sec
0sec
+70702211
+70703311
+70112111
PHONECALL
PHONECALL
WAP
SMS
";

function process($input) {

	$times = $durations = $numbers = $types = $output = array();
	
	$input_arr = explode("\r", trim($input));
	
	// print_r($input_arr);
	
	$section = 1;
	
	foreach ($input_arr as $key => $entry) {
		switch($section) {
			case 1:
				// time
				if (substr(trim($entry), -2) == 'AM' or substr(trim($entry), -2) == 'PM' ) {
					$times[] = $key;
					break;
				} else {
					$section ++;
				}
			
			case 2:
				// duration
				if (substr(trim($entry), -3) == 'sec') {
					$durations[] = $key;
					break;
				} else {
					$section ++;
				}		
			
			case 3:
				// number
				if (substr(trim($entry), 0, 1) == '+') {
					$numbers[] = $key;
					break;
				} else {
					$section ++;
				}		
			
			case 4:
				// type
				$types[] = $key;
			break;
		}
	}
	
	foreach ($types as $key => $type) {
		$row['time'] = trim($input_arr[array_shift($times)]);
		$row['duration'] = trim($input_arr[array_shift($durations)]);
		if (trim($input_arr[$type]) == "WAP") {
			$row['number'] = "N/A";		
		} else {
			$row['number'] = trim($input_arr[array_shift($numbers)]);	
		}
		$row['type'] = trim($input_arr[array_shift($types)]);
		$output[] = $row;
	}
	
	return $output;
}

?>

<pre>

<?php print_r(process($input)); ?>

</pre>

( needs comments... too lazy and proud to add them :-D )

Offline

#13 December 31 2010

longbit
Member

Re: Exercise - Text Processing and More

ok here we ago with JAVA

class CallReport{
public static void main(String arg []){
System.out.println("11pm\t20sec\t+70702211\tphonecall\n12pm\t30sec\t+70703311\tphonecall\n9am\t30sec\tN/A\tWAP\n11AM\t0sec\t+70112111\tSMS);
}
}

Offline

#14 December 31 2010

longbit
Member

Re: Exercise - Text Processing and More

nahh just kidding :/
i wanted to add something, i assumed the bad report will be readed from a text file and the results will wrote to a file as well
so here it is:

import java.io.*;
public class CallReport {

      public static String validateFile(String filepath, BufferedReader reader) throws IOException{
        String s = filepath;
        while(!(new File(s).exists()) && !(new File(s).isFile()))
        {
            System.out.println("File does not exist or file path wsn't inserted\n...enter a valid path: ");
            s = reader.readLine();
        }
        return s;
       }

    public static void main(String[] args)throws IOException {
	InputStreamReader isr = new InputStreamReader(System.in);
	BufferedReader reader = new BufferedReader(isr);
	System.out.print("Enter the report path: ");
	String path = validateFile(reader.readLine(),reader);
	reader = new BufferedReader(new FileReader(path));
        int counter = 0;int i,j;
        String info="";String t,d,n,y;
		t="";d="";n="";y="";
		while((t=reader.readLine())!=null)
		{
			info+=" "+t;
		}
		t="";	
        String data[]=info.split(" ");
        for(String s:data)
        {
            if(s.contains("AM")||s.contains("PM"))
                t=t+" "+s;
            else if(s.contains("sec"))
                d=d+" "+s;
            else if(s.startsWith("+"))
                n=n+" "+s;
            else
                y=y+" "+s;
        }
		t=t.substring(1);
		y=y.substring(2);
		n=n.substring(1);
		d=d.substring(1);
        String duration [] = d.split(" ");
        String time     [] = t.split(" ");
        String service  [] = y.split(" ");
        String nb       [] = n.split(" ");
        String numbers  [] = new String[service.length];
           i=0;j=0;
        for(String s:service)
        {
            if(!s.equals("WAP"))
            {
                numbers[i] = nb[j];
                i++;
                j++;
            }
            else
            {
                numbers[i] = "N/A\t";
                i++;
            }
        }
		BufferedWriter writer = new BufferedWriter(new FileWriter(path.substring(0,(path.lastIndexOf('.')))+"_NewReport.txt"));
		for(int x = 0;x<time.length ; x++)
		{
			System.out.println(time[x]+"\t\t"+duration[x]+"\t\t"+numbers[x]+"\t"+service[x]);
			writer.write(time[x]+"\t\t"+duration[x]+"\t\t"+numbers[x]+"\t"+service[x]);
			writer.newLine();
		}
				writer.close();
        		reader.close();
		
	}
}

Offline

#15 November 10 2012

Ayman
Member

Re: Exercise - Text Processing and More

Very old thread, thought I'd add a simple solution in Python.

times,durations,numbers = [],[],[]
ti,du,nu = 0,0,0

for line in open('input.txt','r'):

    line = line.rstrip()
    
    if(line.endswith("AM") or line.endswith("PM")):
        times.append(line)

    elif(line.endswith("sec")):
        durations.append(line)

    elif(line[0] == "+" and len(line) == 9):
        numbers.append(line)

    elif(line in ("SMS","PHONECALL","WAP")):
        if(line == "WAP"):
            number = "n/a"
        else:
            number = numbers[nu]
            nu = nu + 1
            
        print "{0} {1} {2} {3}".format(times[ti],durations[du],number,line)
        ti = ti + 1
        du = du + 1

There is no need for more than one loop other than the one iterating over the lines of the file as long as the input data is organized the way shown above, and given that the list of types are at the end we use the same loop to iterate through them and compare their types and based on that increment the indexes of the other 3 lists holding the other info.

Offline

#16 November 10 2012

arithma
Member

Re: Exercise - Text Processing and More

What the hell was I thinking when I first replied to MSD. Sometimes my past self embarrasses me. Anyway, it was 2 years ago.
@Ayman: Cool solution, how come you resurrected this thing?

Last edited by arithma (November 10 2012)

Offline

#17 November 10 2012

Ayman
Member

Re: Exercise - Text Processing and More

@arithma haha, I was taking a look at exercises that I checked before all listed here

Offline

#18 November 10 2012

jsaade
Member

Re: Exercise - Text Processing and More

arithma wrote:

What the hell was I thinking when I first replied to MSD. Sometimes my past self embarrasses me. Anyway, it was 2 years ago.
@Ayman: Cool solution, how come you resurrected this thing?

It was like reading something khalil (if you remember) would post :)

Offline

Board footer