Parser, psy a kočky... HELP – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Parser, psy a kočky... HELP – .NET – Fórum – Programujte.comParser, psy a kočky... HELP – .NET – Fórum – Programujte.com

 

GAMA
~ Anonymní uživatel
5 příspěvků
10. 7. 2016   #1
-
0
-

Ahoj,

mám problém s parserem, jde o vytáhnutí dat asi z 50k řádků za hodinu (log). Potřebuji to v live streamu, což už všechno mám mám už dokonce i analýzu, ale problém je, že mám vzorek 50k řádků a na něm je přesně 277 koček, mě se podařilo vytáhnout jen 263. Popíšu problém.

Dám příklad, jak data vypadají

kočka 22 -> data ktery chci vytahnout //to už mám všechno napsaný správně
pes 22 -> data
pes 22 -> data
pes 22 -> data
kočka 47 -> data
pes 47 -> data
pes 47 - > data

koček je přesnej počet 277 a ke každé kočce potřebuji přiřadit a předat třídě prvního psa pod stejným číslem.

kocka 22
pes 22
kocka 47
pes 47

Problém je, že někdy jsou data např. takhle
kocka 55
kocka 57
pes 57
pes 55
pes 55
pes 57
a takhle třeba náhodně
Ale vždy je pes po kočce.

A někdy výjimečně se stane, že chybí pes, takže kočka je, ale nemá se s čím sparovat. To ale nevadí.

Mám to pres FileStream, ale nechapu, že to nevrací x = název.position, nazev.seek (x, orig. begin) takové jaké předávám.
Mám dva parsery, první vytahuje kočky a psy z logfile a další ten, se kterým se teď trápím a který popisuji z nich dělá to co potřebuji...

 NEVŠÍMEJTE SI VŮBEC TECH PARSOVACICH METOD (ty jsou všechny spávně) JEN PODMÍNEK A VRACENÍ POZICE
Takže potřebuji prostě, aby to vzalo všech 277 koček a k nim přiřadilo prvního psa se stejným číslem  [:-)]
Někdy můžou být i např 3 kočky pod sebou  :( Jsem z toho zoufalej...

FileStream fr1 = new FileStream("log.txt", FileMode.Open, FileAccess.ReadWrite);
StreamReader reader1 = new StreamReader(fr1);

string text1;
string[] textarr = { };
string[] textarr1 = { };
string[] textarr2 = { };

bool ToF = false;

while (reader1.EndOfStream == false)
{
    if (ToF == true)
    {
        fr1.Seek(pos009, SeekOrigin.Begin);
        ToF = false;
    }

    text1 = reader1.ReadLine();

    if (text1.Contains("kocka"))
    {
        textarr = text1.Split(' ');
        x++;
        o++;
        IDc[x] = textarr[4];
        card1[x] = textarr[6];
        card2[x] = textarr[8];
        if ((textarr[6].EndsWith("s") == textarr[8].EndsWith("s")) && (textarr[6].EndsWith("d") == textarr[8].EndsWith("d"))
            && (textarr[6].EndsWith("h") == textarr[8].EndsWith("h")) && (textarr[6].EndsWith("c") == textarr[8].EndsWith("c")))
            suited[x] = true;
        else
            suited[x] = false;
        listBox2.Items.Add(x + "\t" + textarr[2] + "\t" + textarr[4] + "\t" + textarr[6] + " " + textarr[8] + "\t" + suited[x]);


        text1 = reader1.ReadLine();
        while (reader1.EndOfStream == false)
        {
            if (text1.Contains("pes") && text1.Contains(textarr[4]))
            {
                textarr1 = text1.Split(' ');
                if (string.Equals(textarr1[9], "'W'"))
                {
                    listBox2.Items.Add(x + "\t" + textarr1[2] + "\t" + textarr[4] + "\t" + "noaction");
                    stav[x] = 0;
                    IDs[x] = textarr1[4];
                }
                else if (text1.Contains("'*'"))
                {
                    textarr1[16] = textarr1[16].Remove(textarr1[16].Length - 1);
                    textarr1[15] = textarr1[15].Remove(textarr1[15].Length - 1);
                    listBox2.Items.Add(x + "\t" + textarr1[2] + "\t" + textarr[4] + "\t" + textarr1[15] + ", " + textarr1[16]);
                    stav[x] = 1;
                    IDs[x] = textarr1[4];
                    stack[x] = int.Parse(textarr1[15]);
                    bb[x] = int.Parse(textarr1[16]);
                }
                else
                {
                    listBox2.Items.Add(x + "\t" + textarr1[2] + "\t" + textarr[4] + "\t" + textarr1[10]);
                    stav[x] = 2;
                    tocall[x] = int.Parse(textarr1[10]);
                    bb[x] = bb[x - 1];
                }
                break;
            }
            else if (text1.Contains("kocka"))
            {
                pos009 = fr1.Position - text1.Length;   //chyba 1. tuhletu pozici to nastavi nekam uplne do hoven asi o 15 radku pod onoho psa, od kteryho potebuji zacit nasledujíci cyklus

                listBox2.Items.Add(pos009 + " " + text1);
                text1 = reader1.ReadLine();
                ToF = true;
            }
            else
            {

                text1 = reader1.ReadLine();

                //tady potřebuji, aby to sem skočilo třeba když tam nebude žádnej pes, kterej by se mohl sparovat a přeskočilo ho to...
            // program zastavi přidávání psů jakmile narazí na kocku, která nemá psa
            //protože ho to hledá tak dlouho, dokud není na eof, což je samozřejmě špatně
            }
        }

        m = 0;
    }
}
Nahlásit jako SPAM
IP: 94.74.242.–
GAMA
~ Anonymní uživatel
5 příspěvků
11. 7. 2016   #2
-
0
-

Tak už po 3 dnech dumání a myslení si, že je moje logika uplne v haji vím čím to je..** Je to tím, že mi pos009 = fr1.Position zobrazuje jen násobky 1024**, takže pozice nefungují, neví někdo jak to vyřešit?

pozice hned prvního řádku je 1024 a potom po 10ti kočkách je už 2048 a tak dále... Jestli mi někdo pomůže vyřešit tohle tak si s tím parserem už poradím  [:-)]  Když jsem vracel pozici, tak to samozřejmě vrátilo na úplnej nesmysl, kterej byl někde v intervalu 1024.

To by bylo abych neuměl vyhledat kočku, potom příslušnýho psa, vrátit pozici a znovu  [:-)]

Díky moc!!!

Nahlásit jako SPAM
IP: 94.74.242.–
Kit+15
Guru
11. 7. 2016   #3
-
0
-

#1 GAMA
Doporučuji metodu Seek() vůbec nepoužívat. V daném případě nedává její použití žádný smysl a může způsobit ztrátu vstupních dat.

Místo  

textarr = text1.Split(' ');

má být 

string[] textarr = text1.Split(' ');

Zvykni si na to. Je to tak přehlednější a proměnná bude automaticky zlikvidována před dalším průchodem cyklem.

Nevidím konce řádek, možná v nich ta chyba může být schovaná. Dodržuj doporučenou délku max. 80 znaků.

Napiš si to raději objektově, ať se v tom lépe vyznáš. V takové zmatené špagetě se chyba snadno schová.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
P
~ Anonymní uživatel
212 příspěvků
11. 7. 2016   #4
-
0
-

   

using System;
using System.Collections.Generic;
using System.IO;

namespace GAMA
{
    public class Kockopes
    {
        private int _cislo;
        private string _kocka;
        private string _pes;

        public Kockopes(int cislo, string kocka, string pes)
        {
            _cislo = cislo;
            _kocka = kocka;
            _pes = pes;
        }

        public override string ToString()
        {
            return string.Format("cislo: {0}, kocka: {1}, pes: {2}", _cislo, _kocka, _pes);
        }

        public static void ProcessFile(string filename)
        {
            //predpoklada se, ze radky josu ve tvaru
            //kocka X -> data
            //pes X -> data
            try
            {
                using (var sr = new StreamReader(filename))
                {
                    string line;
                    Dictionary<int, string> kocky = new Dictionary<int, string>();
                    while ((line = sr.ReadLine()) != null)
                    {
                        string[] arr = line.Split(new char[] { ' ' }, 4);
                        switch (arr[0])
                        {
                            case "kocka":
                                //kocka se prida do seznamu kocek 
                                kocky.Add(int.Parse(arr[1]), arr[3]);
                                break;
                            case "pes":
                                var key = int.Parse(arr[1]);
                                string value;
                                //zpracuje prvniho psa, ktery nasleduje po kocce se stejnym cislem
                                //po zpracovani prvniho psa vyradi kocku ze seznamu kocek, takze dalsi psi se stejnym cislem se uz nezpracuji
                                //zpracuji se pouze kocky, ke kterym existuje nejaky pes
                                if (kocky.TryGetValue(key, out value))
                                {
                                    Console.WriteLine(new Kockopes(key, value, arr[3]));
                                    kocky.Remove(key);
                                }
                                break;
                            default:
                                throw new NotSupportedException(arr[0]);
                        }
                    }
                    //nakonec se zpracuji kocky, ke kterym neni zadny pes
                    {
                        foreach (var kvp in kocky)
                        {
                            Console.WriteLine(new Kockopes(kvp.Key, kvp.Value, string.Empty));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                //zpracovani chyby cteni souboru
            }
        }
    }
}
Nahlásit jako SPAM
IP: 85.93.116.–
peter
~ Anonymní uživatel
4016 příspěvků
11. 7. 2016   #5
-
0
-

No, a kdyz si udelas pole?

"kocka" -> "id" -> existuje pole[id] ? nic : nic
"pes" -> "id", "nazev psa" -> existuje pole[id] ? nic : pole[id] = "nazev psa"
Cili, pouze pes naplnuje pole[id] prvnim psem, ktery ma stejne id. Prvni radek tam vubec nemusi byt, tedy.
Ale, pokud neplati, ze ma kazda kocka alespon 1 psa, pak nebude sedet pocet kocek.

"kocka" -> "id", "nazev kocky" -> existuje pole[id] ? (existuje pole[id]['kocka'] ? nic : pole[id]['kocka'] = "nazev kocky") : nic
"pes" -> "id", "nazev psa" -> existuje pole[id] ? (existuje pole[id]['pes'] ? nic : pole[id]['pes'] = "nazev psa"
Cili, i kdyby neexistoval ke kocce zadny pes, tak bude v seznamu.

podminka ? true() : false()
if (podminka) {true();} else {false();}
To jen na vysvetleni toho zapisu, if, podminka, kladna moznost, zaporna. (nechtelo se mi to rozepisovat do slov)

Nahlásit jako SPAM
IP: 2001:718:2601:26c:cce1:59...–
P
~ Anonymní uživatel
212 příspěvků
11. 7. 2016   #6
-
0
-

#5 peter
Ano, slo by drzet si v pameti seznam vsech nactenych kocek a psu. Ale pokud se nebude nejakym zpusobem uvolnovat, tak se pamet po nejake dobe zaplni. K tomu by doslo i pri mem reseni, pokud by bylo hodne kocek, ke kterym neni pes.

Nahlásit jako SPAM
IP: 85.93.116.–
Kit+15
Guru
11. 7. 2016   #7
-
0
-

#6 P
Nebylo by jednodušší se s tím nepárat v C#, ale rovnou ta data sypat do databáze? Odpadnou kolekce i problémy.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
P
~ Anonymní uživatel
212 příspěvků
11. 7. 2016   #8
-
0
-

Tak urcite, nicmene nevim, co s tim realne dela a tak vychazim ze zadani dotazu.

Nahlásit jako SPAM
IP: 85.93.116.–
Kit+15
Guru
11. 7. 2016   #9
-
0
-

#8 P
Ten příklad je nešťastne zvolen. Vlastně se z něj dá odvodit, že "kočka má <0..N> psů". To je pro mne stravitelné pouze v případě, že by ty kočky byly dvounohé.

Převedeno do objektů je to kolekce koček, z nichž každá má kolekci psů. Drobet to kulhá, protože tento přístup negarantuje, aby pes mohl být vlastněn pouze jednou kočkou.

Převedeno do relací je to dvojice tabulek kočka a pes s vazbou 1:N. Pes má kromě primárního klíče ještě cizí klíč kočka_id, který váže psy na kočky. Zde nemůže dojít k situaci, že by pes patřil dvěma kočkám.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
11. 7. 2016   #10
-
0
-

#1 GAMA
Ještě mě napadá: Pokud je nějaké kočce přiřazen pes, mají se ostatní psi s jejím číslem ignorovat?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
GAMA
~ Anonymní uživatel
5 příspěvků
11. 7. 2016   #11
-
0
-

Super!!! Díky moc! :)

Ted nejsem doma tak napíšu až budu doma a vyzkouším :-)

Nahlásit jako SPAM
IP: 94.74.242.–
P
~ Anonymní uživatel
212 příspěvků
12. 7. 2016   #12
-
0
-

#10 Kit
Podle zadani ano:

koček je přesnej počet 277 a ke každé kočce potřebuji přiřadit a předat třídě prvního psa pod stejným číslem.

Nahlásit jako SPAM
IP: 85.93.116.–
P
~ Anonymní uživatel
212 příspěvků
12. 7. 2016   #13
-
0
-

#9 Kit
Kocka nema kolekci psu. Ke kazde kocce potrebuje pouze jednoho prvniho psa se stejnym cislem jako ma ta kocka, pricemz takovy pes nemusi existovat. Tedy ke kazde kocce je 0..1 psu.

Nahlásit jako SPAM
IP: 85.93.116.–
GAMA
~ Anonymní uživatel
5 příspěvků
14. 7. 2016   #14
-
0
-

Vyřešeno tímto kódem...

díky moc, za všechny odpovědi :)

potřebuji ještě vyřešit, jak udělat, aby si pamatoval "přesnou" pozici kde skončil se četním v logu???

FileStream logs = new FileStream("log.txt", FileMode.Open, FileAccess.ReadWrite);
            StreamReader reader1 = new StreamReader(logs);

            logs.Seek(logpos1, SeekOrigin.Begin);

            while (!reader1.EndOfStream)
            {
                lines.Add(reader1.ReadLine());
            }
            logpos1 = logs.Position;

Tohle nastavuje pozici někam na konec, ale určitě ne přesně, protože, když zkopíruju ten log a dám ho ještě jednou za původní tak to nepřečte vůbec první 4 kočky u toho vložení a je tam problém s tím, že když dám, aby to ukazovalo pozici po každým přečteným řádku,tak opět první řádek má už hodnotu 1024 a 8x za sebou, a pořád to jde po 1024, potom 2048 apod...  [:(]

Někde jsem četl, že se to nemá vůbec používat , pokud nechci ztratit data... seek a position  [:(]

Nahlásit jako SPAM
IP: 94.74.242.–
GAMA
~ Anonymní uživatel
5 příspěvků
14. 7. 2016   #15
-
0
-

Vyřešil jsem to tak, že jsem se vykašlal na pozice a vždycky vymazal celej log po tom cyklu  [:-)]

Nahlásit jako SPAM
IP: 94.74.242.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 25 hostů

Podobná vlákna

Parser v c# — založil Misiak

Parser — založil flyer

Parser z M Onlajny — založil JirkaX

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý