NPRG035 Jazyk C# a platforma .NET

Každý neuvedený předmět
Uživatelský avatar
Petr-H
Matfyz(ák|ačka) level II
Příspěvky: 81
Registrován: 30. 1. 2006 14:18
Typ studia: Informatika Mgr.
Bydliště: VŠK 17. listopadu
Kontaktovat uživatele:

NPRG035 Jazyk C# a platforma .NET

Příspěvek od Petr-H »

Zpracování tabulky

Zadání:
Na vstupu tabulka obsahující data rozdělená na sloupce a řádky, jednotlivé položky v řádku jsou oddělené libovolným množstvím mezer a tabulátorů. Úkolem je tuto tabulku zformátovat, setřídit dle sloupce uvedeného za názvem výstupního souboru, a tabulka musí začínat sloupci uvedenými jako další argumenty (jejich počet je volitelný).

Použití:

Kód: Vybrat vše

zpracovaniTabulky.exe Vstup.txt Vystup.txt zbozi prodejce zbozi mesic
Vstup:

Kód: Vybrat vše

mesic	zbozi	typ	prodejce	mnozstvi	cena	trzba
         leden	   brambory		tuzemske	Bartak	10895	12	      130740
leden	brambory	vlastni	Celestyn	15478	10	154780
leden	jablka	dovoz	Adamec	1321	                                  30	39630
leden	melouny	dovoz	Adamec	120	37	                      4440
leden	okurky	dovoz	Bartak	4258	32	136256
leden	papriky	dovoz	Bartak	453	51	23103
leden	     pomerance	   dovoz	Adamec	4568	20	91360
		unor	brambory	tuzemske	Celestyn	1258	13	16354
unor	brambory	vlastni	Celestyn	7851	10	78510
unor	jablka	dovoz	Adamec	989	23	22747
unor	jablka	tuzemske	Bartak	1423	13	18499
unor	papriky	dovoz	Bartak	545	49	26705
unor	rajcata			tuzemske	Celestyn	231	42	9702
brezen	brambory dovoz	Adamec	241	28	6748
brezen	brambory tuzemske	Celestyn	15854	12	190248
brezen	jablka	dovoz	Adamec	1234	25	30850
brezen	jablka	vlastni	Celestyn	745	12	8940
brezen	papriky	dovoz	Bartak	856	36	30816
brezen	pomerance	dovoz	Adamec	3226	19	61294
Výstup:

Kód: Vybrat vše

prodejce zbozi     mesic  typ      mnozstvi cena trzba  
Adamec   brambory  brezen dovoz    241      28   6748   
Celestyn brambory  brezen tuzemske 15854    12   190248 
Celestyn brambory  unor   vlastni  7851     10   78510  
Celestyn brambory  unor   tuzemske 1258     13   16354  
Celestyn brambory  leden  vlastni  15478    10   154780 
Bartak   brambory  leden  tuzemske 10895    12   130740 
Bartak   jablka    unor   tuzemske 1423     13   18499  
Adamec   jablka    brezen dovoz    1234     25   30850  
Celestyn jablka    brezen vlastni  745      12   8940   
Adamec   jablka    unor   dovoz    989      23   22747  
Adamec   jablka    leden  dovoz    1321     30   39630  
Adamec   melouny   leden  dovoz    120      37   4440   
Bartak   okurky    leden  dovoz    4258     32   136256 
Bartak   papriky   unor   dovoz    545      49   26705  
Bartak   papriky   brezen dovoz    856      36   30816  
Bartak   papriky   leden  dovoz    453      51   23103  
Adamec   pomerance brezen dovoz    3226     19   61294  
Adamec   pomerance leden  dovoz    4568     20   91360  
Celestyn rajcata   unor   tuzemske 231      42   9702   
Ukázkové řešení:

Kód: Vybrat vše

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections.Specialized;

namespace zpracovaniTabulky
{
    class Table
    {
        private class Row : IComparable<Row>
        {
            private readonly Table table;

            private List<string> data;
            public List<string> Data
            {
                get { return this.data; }
            }

            public Row(Table table, string[] data)
            {
                this.table = table;
                this.data = new List<string>(data);
            }

            public string Write(List<int> prefferedColumns, List<int> widths)
            {
                StringBuilder row = new StringBuilder();
                foreach (int index in prefferedColumns)
                {
                    row.AppendFormat("{0,-" + (widths[index] + 1) + "}", data[index]);
                }
                for (int i = 0; i < data.Count; ++i)
                {
                    if (!prefferedColumns.Contains(i))
                    {
                        row.AppendFormat("{0,-" + (widths[i] + 1) + "}", data[i]);
                    }
                }
                return row.ToString();
            }

            #region IComparable<Row> Members

            public int CompareTo(Row other)
            {
                return Comparer<string>.Default.Compare(this.data[table.sortColumn], other.data[table.sortColumn]);
            }

            #endregion
        }

        private Row header;
        private List<Row> rows;
        private List<int> widths;
        private List<int> prefferedColumns;
        private int sortColumn;

        public int Width
        {
            get { return this.header.Data.Count; }
        }

        public int Height
        {
            get { return this.rows.Count; }
        }

        public string SortColumn
        {
            set
            {
                this.sortColumn = header.Data.IndexOf(value);
                if (this.sortColumn == -1)
                {
                    throw new ArgumentException("Invalid sort column");
                }
                this.rows.Sort();
            }
        }

        public List<string> PrefferedColumns
        {
            set
            {
                this.prefferedColumns = new List<int>();
                foreach (string column in value)
                {
                    int columnIndex = header.Data.IndexOf(column);
                    if (columnIndex != -1)
                    {
                        this.prefferedColumns.Add(columnIndex);
                    }
                    else
                    {
                        throw new ArgumentException("Invalid column");
                    }
                }
            }
        }

        public void Read(Stream stream)
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                string line;
                this.widths = new List<int>();

                if ((line = reader.ReadLine()) != null)
                {
                    string[] strings = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                    this.header = new Row(this, strings);
                    foreach (string column in strings)
                    {
                        widths.Add(column.Length);
                    }
                }

                this.rows = new List<Row>();
                while ((line = reader.ReadLine()) != null)
                {
                    string[] strings = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                    if (strings.Length != this.Width)
                    {
                        throw new Exception(string.Format("Invalid number of columns on row {0}", this.Height + 1));
                    }
                    this.rows.Add(new Row(this, strings));
                    for (int i = 0; i < this.widths.Count; i++)
                    {
                        if (this.widths[i] < strings[i].Length)
                        {
                            this.widths[i] = strings[i].Length;
                        }
                    }
                }
            }
        }

        public void Write(Stream stream)
        {
            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.WriteLine(header.Write(this.prefferedColumns, this.widths));
                foreach (Row row in this.rows)
                {
                    writer.WriteLine(row.Write(this.prefferedColumns, this.widths));
                }
            }
        }
    }

    class Program
    {
        private static Table table = new Table();

        static void Main(string[] args)
        {
            // open input file
            FileInfo inputFile = new FileInfo(args[0]);
            if (!inputFile.Exists)
            {
                Console.Error.WriteLine("File {0} does not exists", inputFile.Name);
                return;
            }
            // read table
            using (FileStream stream = inputFile.OpenRead())
            {
                table.Read(stream);
            }

            // sort table
            string sortColumn = args[2];
            try
            {
                table.SortColumn = sortColumn;
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
            }

            // read output columns
            List<string> columns = new List<string>();
            for (int i = 3; i < args.Length; ++i)
            {
                columns.Add(args[i]);
            }
            try
            {
                table.PrefferedColumns = columns;
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
            }

            // open file
            FileInfo outputFile = new FileInfo(args[1]);
            // write table
            using (FileStream stream = outputFile.OpenWrite())
            {
                table.Write(stream);
            }
        }
    }
}
jeza
Matfyz(ák|ačka) level I
Příspěvky: 4
Registrován: 13. 1. 2007 13:06

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od jeza »

Dnes (16.1., 10:00) byl jednoduchy webovy server. Mel umet:
- vyrizovat vzdy jen jeden pozadavek (zadna vlakna)
- vratit libovolny soubor z DocumentRootu (ten dostal jako parametr),
- vypsat obsah libovolneho adresare - s odkazy na soubory a podslozky + moznost tridit podle nazvu, koncovky a velikosti,
- nahlasit chybu pri spatnem pozadavku
- chybu 404 - Not Found - kdyz nenasel soubor nebo adresar

Celkem jednoduche a pekne popsane - bylo jasne co (a jak) delat.
Inv
Matfyz(ák|ačka) level I
Příspěvky: 13
Registrován: 20. 1. 2006 23:48
Typ studia: Informatika Bc.
Bydliště: 17. listopad A1602
Kontaktovat uživatele:

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od Inv »

Jeste k zadani toho webserveru:
Server mel umet odpovidat na klasicky HTTP GET, tj. klient posle HTTP GET /dir/dir2/hello.html a pak spoustu dalsich hlavicek, ktere ignorujeme. Na takovy dotaz odpovime obsahem souboru (napr. c:\web\dir\dir\hello.html, pokud je server pusten s parametrem c:\web)
V pripade ze v GETu prijde jen /dir , ma server vygenerovat html s obsahem adresare ve forme hypertextovych odkazu.
Server nemusi umet obslouzit vice klientu najednou, takze nic asynchronniho / vlakna. Kdyz nekdo stahuje, nikdo se uz nepripoji.

Ja jsem to delal zhruba takhle:

Kód: Vybrat vše

    public class WebServer
    {
        int port;        // port na kterem poslouchat
        string dir;     // adresar ve filesystemu, ktery ma byt korenovy pri dotazu http://localhost:8080
        TcpListener listener = null;

        public WebServer(string port, string dir)
        {
            this.port = int.Parse(port);
            this.dir = dir;
            listener = new TcpListener(this.port);
        }

        // spustit server
        public void Start()
        {
            // zacit poslouchat
            listener.Start();

            while (true)
            {
                // blokuje a ceka na spojeni
                TcpClient client = listener.AcceptTcpClient();

                // odtud budeme cist dotaz i sem budeme vracet odpoved
                Stream stream = client.GetStream();

                // odpovidat budeme binarne - proste posleme obsah souboru, ktery klient chce
                BinaryWriter writer = new BinaryWriter(stream);

                // na dotazy od klienta se budeme divat jako na ASCII
                StreamReader reader = new StreamReader(writer.BaseStream, Encoding.ASCII);

                 // blokuje, dokud klient neco neposle
                 string line = reader.ReadLine();
    
                string path = 
                // ...
                // rozparsovat line, ziskame url, toto url prevedeme na absolutni cestu ve filesystemu
                // ...

                // sezrat zbytek hlavicek, ktere nas nezajimaji
                while (line != null)
                {
                    line = reader.ReadLine();
                }

                // odpovedet
                DirectoryInfo directory = new DirectoryInfo(path);
                if (directory.Exists)
                {
                    // vysypat do writeru html vypis adresare
                    writer.Write(Encoding.ASCII.GetBytes("<html><head>");
 
                    // z tohohle vygenerovat html                   
                    FileInfo[] files = directory.GetFiles();
                    DirectoryInfo[] dirs = directory.GetDirectories();
                    // ...
                }
                else
                {
                    FileInfo file = new FileInfo(path);
                    if (file.Exists)
                    {
                            // vysypat do writeru soubor
                            Stream fs = file.OpenRead();
                            BinaryReader fr = new BinaryReader(fs);
                            byte[] buffer = new byte[4096];
                            int read = fr.Read(buffer, 0, 4096);
                            while (read > 0)
                            {
                                writer.Write(buffer, 0, read);
                                read = fr.Read(buffer, 0, 4096);
                            }
                    }
                }
                
                // zavreme writer i se streamem, aby klient poznal, ze data od nas konci
                writer.Close();
            } // while(true)
        } // Start()
    }

+ samozrejme osetreni vyjimek, vraceni 404 not found apod.
MrCooper
Matfyz(ák|ačka) level II
Příspěvky: 59
Registrován: 17. 1. 2006 17:54

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od MrCooper »

Ahoj,

muzu se zeptat tech co uz na testu byli, jake jsou dovolene pomucky? Pouze napoveda Visual studia, nebo internet, knihy...? Kolik je casu a jak moc je "zkousejici" prisny?

Diky, M
Uživatelský avatar
Petr-H
Matfyz(ák|ačka) level II
Příspěvky: 81
Registrován: 30. 1. 2006 14:18
Typ studia: Informatika Mgr.
Bydliště: VŠK 17. listopadu
Kontaktovat uživatele:

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od Petr-H »

Povolenými pomůckami je MSDN Library a tištěná literatura, přístup na internet povolený není. Časový limit je 3 hodiny.
Ceberus
Matfyz(ák|ačka) level I
Příspěvky: 22
Registrován: 28. 10. 2007 23:37
Typ studia: Informatika Mgr.
Bydliště: Petřvald u N.J. / kolej 17.listopadu
Kontaktovat uživatele:

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od Ceberus »

Na zkoušce z OOP bylo možné si donést i flash disk s potřebnýma dokumentama - je to možné i u zkoušky ze C# ?
MrCooper
Matfyz(ák|ačka) level II
Příspěvky: 59
Registrován: 17. 1. 2006 17:54

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od MrCooper »

Petr H píše:Povolenými pomůckami je MSDN Library a tištěná literatura, přístup na internet povolený není. Časový limit je 3 hodiny.
Super, diky, ta literatura me docela potesila.
Uživatelský avatar
Petr-H
Matfyz(ák|ačka) level II
Příspěvky: 81
Registrován: 30. 1. 2006 14:18
Typ studia: Informatika Mgr.
Bydliště: VŠK 17. listopadu
Kontaktovat uživatele:

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od Petr-H »

Ceberus píše:Na zkoušce z OOP bylo možné si donést i flash disk s potřebnýma dokumentama - je to možné i u zkoušky ze C# ?
Tato možnost zmiňována nebyla, což nemusí znamenat že je zakázána, osobně si ale myslím že povolena nebude.
Medved
Admin(ka) level I
Příspěvky: 168
Registrován: 30. 5. 2006 21:18

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od Medved »

Ceberus píše:Na zkoušce z OOP bylo možné si donést i flash disk s potřebnýma dokumentama - je to možné i u zkoušky ze C# ?
Myslim, ze neni... (90% jistota)
kaktus
Matfyz(ák|ačka) level I
Příspěvky: 5
Registrován: 13. 1. 2006 21:00

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od kaktus »

Tak dnes som bol od 10:00 na zapoctovom teste zo C#. To zadanie bolo na prvy a druhy pohlad vcelku drsne, ale potom od tretieho pohladu to uz vcelku islo.
A ake bolo teda zadanie? Poznate kontingnecne tabulky (napr. v Exceli)? Tak presne o to islo, vytvorit k danej tabulke kontingencnu tabulku.

Vstup - Zelenina.txt:

Kód: Vybrat vše

mesic	zbozi	typ	prodejce	mnozstvi	cena	trzba
         leden	   brambory		tuzemske	Bartak	10895	12	      130740
leden	brambory	vlastni	Celestyn	15478	10	154780
leden	jablka	dovoz	Adamec	1321	                                  30	39630
leden	melouny	dovoz	Adamec	120	37	                      4440
leden	okurky	dovoz	Bartak	4258	32	136256
leden	papriky	dovoz	Bartak	453	51	23103
leden	     pomerance	   dovoz	Adamec	4568	20	91360
		unor	brambory	tuzemske	Celestyn	1258	13	16354
unor	brambory	vlastni	Celestyn	7851	10	78510
unor	jablka	dovoz	Adamec	989	23	22747
unor	jablka	tuzemske	Bartak	1423	13	18499
unor	papriky	dovoz	Bartak	545	49	26705
unor	rajcata			tuzemske	Celestyn	231	42	9702
brezen	brambory dovoz	Adamec	241	28	6748
brezen	brambory tuzemske	Celestyn	15854	12	190248
brezen	jablka	dovoz	Adamec	1234	25	30850
brezen	jablka	vlastni	Celestyn	745	12	8940
brezen	papriky	dovoz	Bartak	856	36	30816
brezen	pomerance	dovoz	Adamec	3226	19	61294
parametre na prikazovom riadku

Kód: Vybrat vše

kontingenc.exe Zelenina.txt Vystup.txt trzba prodejce mesic zbozi typ
vystup - Vystup.txt

Kód: Vybrat vše

leden brambory tuzemske Bartak:130740 
               vlastni Celestyn:154780 
      jablka dovoz Adamec:39630 
      melouny dovoz Adamec:4440 
      okurky dovoz Bartak:136256 
      papriky dovoz Bartak:23103 
      pomerance dovoz Adamec:91360 
unor brambory tuzemske Celestyn:16354 
              vlastni Celestyn:78510 
     jablka dovoz Adamec:22747 
            tuzemske Bartak:18499 
     papriky dovoz Bartak:26705 
     rajcata tuzemske Celestyn:9702 
brezen brambory dovoz Adamec:6748 
                tuzemske Celestyn:190248 
       jablka dovoz Adamec:30850 
              vlastni Celestyn:8940 
       papriky dovoz Bartak:30816 
       pomerance dovoz Adamec:61294 
Na prikazovom riadku boli povinne styri parametre, dalsie boli nepovinne:

Kód: Vybrat vše

kontingenc.exe <vstup> <vystup> <stlpec, cez ktory sa pocita> <zakladny stlpec konting. tabulky> <detailizujuce stlpce konting. tabulky>
Riadky v ramci jednej podskupiny nemuseli byt nijak specialne usporiadane.
Este to malo jedno rozsirenie. Kontingencna tabulka nemusi iba sumarizovat. Aka funkcia sa bude pouzivat sa urci pomocou parametru <stlpec, cez ktory sa pocita>. Napr.
trzba - sumarizacia cez stlpec trzba
soucet_z_trzba - to iste
prumer_z_trzba - priemer z trzby
max_z_trzba - maximum z trzby

Najlepsie je to vidiet na prikladoch. Do prilohy preto pridavam este subor s ukazkovymi vstupmi a vystupmi. Prajem vela stastia na dalsich terminoch, cafte.
Přílohy
UkazkovaData.pdf
ukazkove vstupy a vystupy
(131.04 KiB) Staženo 343 x
kaktus
Matfyz(ák|ačka) level I
Příspěvky: 5
Registrován: 13. 1. 2006 21:00

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od kaktus »

Medved píše:
Ceberus píše:Na zkoušce z OOP bylo možné si donést i flash disk s potřebnýma dokumentama - je to možné i u zkoušky ze C# ?
Myslim, ze neni... (90% jistota)
No na dnesnom teste povedal na zaciatku, ze ak mame nejake materialy v elektronickej podobe, tak si ich mame hned stiahnut na lokal. V nasledujucom priebehu skusky bolo pouzivanie internetu a dat z flesky zakazane. Takze slajdy si nie je potreba tlacit, zachranite tym kus lesa !!!
Pz
Matfyz(ák|ačka) level I
Příspěvky: 20
Registrován: 24. 1. 2006 12:20
Typ studia: Informatika Bc.

Zapoctovy test 22.1.2006

Příspěvek od Pz »

Nic moc, spis nic nez moc.

Zadani: Naprogramujte konzolovy solitaire (ano presne tak).

hra vypada asi takto:

Kód: Vybrat vše

    1 | 2 | 3 | 4 | 5 | 6 | 7
00: XXX 2K      [ ] AK  [ ] [ ]

01: 5S  XXX XXX XXX XXX XXX XXX
02:    7H  XXX XXX XXX XXX XXX XXX
Those who want, try to find the way. Those who do not want, try to find the reason.
Pz
Matfyz(ák|ačka) level I
Příspěvky: 20
Registrován: 24. 1. 2006 12:20
Typ studia: Informatika Bc.

Zap. test 22.1.2008

Příspěvek od Pz »

Prvni veta p. Jezka pred zacatkem: "Ti, co budou brzo hotovi, si muzou zahrat solitera..."

Dnesni zadani... wait for it...

Naprogramujte konzolovy solitaire. Yes.

Celou hru to chtelo vypisovat do konzoly (s rozumnym formatovanim), prikazy se zadavaly formatem:
1 (klik na posledni kartu v prvnim sloupci - otocena -> vyhodit nahoru, neotocena -> otocit)
1.0 (klik na 1. sloupec; 0. radek = balicek karet => vzit novou kartu; 1.1 by bylo vyhodit kartu na hromadce do finalni hromadky)
4-2 (presun posledni karty 4. sloupce do 2. sloupce)
4.1-2 (presun blok karet ze 4. sloupce pocinaje 1. radkem do sloupce 2)

a potom

save path (uloz rozdani karet a historii prikazu do souboru)
quit (vypis inteligenci uzivatele...)

Melo to krom ukladani ze souboru taky umet nacist data - rozdani karet na jednom radku souboru, prikazy na druhem,
podle karet rozdat a prikazy odsimulovat (tak se to pak i testovalo - v jednom testovacim souboru to dohralo hru do konce).

Soubor teda vypadal asi takto:
H2,S5,DK,... (prvni pismeno barva (anglicka zkratka), zbytek hodnota (A,2..10,J,Q,K))
1.0,1.0,2,4-2,... (nova karta z balicku, jeste jedna, automaticky hodit kartu z 2. sloupce nahoru, presun ze 4. na 2. sloupec...)


Nejvetsi peklo jsem mel na zacatku rozmyslet si jak to poradne reprezentovat, pak kdyz uz jsem naparsoval data ze souboru a taky prikazy, tak to byl jeden oooobri if {} else {}, ktery ten prikaz zpracoval - bud jestli se klika nebo presouva, a tam osetreni vsech pripadu. Nic extra elegantniho ale po 3.5 hodinach jsem to mel jako ctvrty (odchazel jsem kolem 20:15 z labu...).

Myslim ze to nebylo az tak tezke, jako spis pracne - bylo hromada ruznych typu prikazu a vsechny se musely nejak osetrit. Pouzival jsem tam hlavne arraye a Listy, zadne dalsi struktury nebyly treba. Pak se to pustilo na soubor, samo se to dohralo do konce (v souboru byly i prikazy s hrou az do konce) a bylo.

Tak drzim palce ostatnim, ale takove zadani jsem teda necekal... :roll:
Those who want, try to find the way. Those who do not want, try to find the reason.
MrCooper
Matfyz(ák|ačka) level II
Příspěvky: 59
Registrován: 17. 1. 2006 17:54

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od MrCooper »

Muzu se zeptat, jake jste pouzivali datove struktury u te kontingencni tabulky? Ja se to snazil doma cvicne splacat z nejakych Dictionary a docela jsem si vylamal zuby... :(
Tom
Matfyz(ák|ačka) level I
Příspěvky: 17
Registrován: 1. 1. 2007 22:29
Typ studia: Informatika Mgr.

Re: NPRG035 Jazyk C# a platforma .NET

Příspěvek od Tom »

MrCooper píše:Muzu se zeptat, jake jste pouzivali datove struktury u te kontingencni tabulky? Ja se to snazil doma cvicne splacat z nejakych Dictionary a docela jsem si vylamal zuby... :(
Použij ukázkové řešení z prvního příspěvku tohoto fóra. Domnívám se, že řešení bude jen o něco málo rozšířený tenhle zdroják.
Petr H píše: Ukázkové řešení:

Kód: Vybrat vše

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections.Specialized;

namespace zpracovaniTabulky
{
    class Table
    {
        private class Row : IComparable<Row>
        {
            private readonly Table table;

            private List<string> data;
            public List<string> Data
            {
                get { return this.data; }
            }

            public Row(Table table, string[] data)
            {
                this.table = table;
                this.data = new List<string>(data);
            }

            public string Write(List<int> prefferedColumns, List<int> widths)
            {
                StringBuilder row = new StringBuilder();
                foreach (int index in prefferedColumns)
                {
                    row.AppendFormat("{0,-" + (widths[index] + 1) + "}", data[index]);
                }
                for (int i = 0; i < data.Count; ++i)
                {
                    if (!prefferedColumns.Contains(i))
                    {
                        row.AppendFormat("{0,-" + (widths[i] + 1) + "}", data[i]);
                    }
                }
                return row.ToString();
            }

            #region IComparable<Row> Members

            public int CompareTo(Row other)
            {
                return Comparer<string>.Default.Compare(this.data[table.sortColumn], other.data[table.sortColumn]);
            }

            #endregion
        }

        private Row header;
        private List<Row> rows;
        private List<int> widths;
        private List<int> prefferedColumns;
        private int sortColumn;

        public int Width
        {
            get { return this.header.Data.Count; }
        }

        public int Height
        {
            get { return this.rows.Count; }
        }

        public string SortColumn
        {
            set
            {
                this.sortColumn = header.Data.IndexOf(value);
                if (this.sortColumn == -1)
                {
                    throw new ArgumentException("Invalid sort column");
                }
                this.rows.Sort();
            }
        }

        public List<string> PrefferedColumns
        {
            set
            {
                this.prefferedColumns = new List<int>();
                foreach (string column in value)
                {
                    int columnIndex = header.Data.IndexOf(column);
                    if (columnIndex != -1)
                    {
                        this.prefferedColumns.Add(columnIndex);
                    }
                    else
                    {
                        throw new ArgumentException("Invalid column");
                    }
                }
            }
        }

        public void Read(Stream stream)
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                string line;
                this.widths = new List<int>();

                if ((line = reader.ReadLine()) != null)
                {
                    string[] strings = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                    this.header = new Row(this, strings);
                    foreach (string column in strings)
                    {
                        widths.Add(column.Length);
                    }
                }

                this.rows = new List<Row>();
                while ((line = reader.ReadLine()) != null)
                {
                    string[] strings = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                    if (strings.Length != this.Width)
                    {
                        throw new Exception(string.Format("Invalid number of columns on row {0}", this.Height + 1));
                    }
                    this.rows.Add(new Row(this, strings));
                    for (int i = 0; i < this.widths.Count; i++)
                    {
                        if (this.widths[i] < strings[i].Length)
                        {
                            this.widths[i] = strings[i].Length;
                        }
                    }
                }
            }
        }

        public void Write(Stream stream)
        {
            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.WriteLine(header.Write(this.prefferedColumns, this.widths));
                foreach (Row row in this.rows)
                {
                    writer.WriteLine(row.Write(this.prefferedColumns, this.widths));
                }
            }
        }
    }

    class Program
    {
        private static Table table = new Table();

        static void Main(string[] args)
        {
            // open input file
            FileInfo inputFile = new FileInfo(args[0]);
            if (!inputFile.Exists)
            {
                Console.Error.WriteLine("File {0} does not exists", inputFile.Name);
                return;
            }
            // read table
            using (FileStream stream = inputFile.OpenRead())
            {
                table.Read(stream);
            }

            // sort table
            string sortColumn = args[2];
            try
            {
                table.SortColumn = sortColumn;
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
            }

            // read output columns
            List<string> columns = new List<string>();
            for (int i = 3; i < args.Length; ++i)
            {
                columns.Add(args[i]);
            }
            try
            {
                table.PrefferedColumns = columns;
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
            }

            // open file
            FileInfo outputFile = new FileInfo(args[1]);
            // write table
            using (FileStream stream = outputFile.OpenWrite())
            {
                table.Write(stream);
            }
        }
    }
}
Odpovědět

Zpět na „Ostatní“