• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wyświetlanie błedu poprzez wczytanie pliku.txt

Object Storage Arubacloud
0 głosów
380 wizyt
pytanie zadane 18 czerwca 2023 w C i C++ przez martinez369 Początkujący (460 p.)

Cześć mam taki problem do rozwiązania otóż jak wczytuje dany plik,txt z zawartością imie,nazwisko,NIP i kwota zawsze wywala błąd że numer NIP jest nie prawidłowy z jak chce odczytać plik rozliczenia.txt to jaką bym kwote nie podał czy na + czy na - daną liczbę to nadal jest błąd proszę o pomoc i wytłumaczenie problemu z góry dziękuje a oto treść zadania

Napisać pomocnicze biblioteki oraz program główny dla następującego zadania:
Centralna Policja Podatkowa raz w roku kontroluje zeznania podatkowe obywateli Fiskustanu. Lista
podatników nazywa się "podatnicy.txt" i zawiera ich dane uporządkowane rosnąco wg nazwiska
i dalej imienia w formacie (kolejne linie):
NIP (10-cyfrowy numer identyfikacji podatkowej)
Nazwisko Imię (oddzielone odstępem)
<pusta linia>
Plik z rozliczeniami podatników nazywa się "rozliczenia.txt" i zawiera liczbę linii zgodną z liczbą
podatników. Każda linia zawiera kwotę rozliczenia odpowiadającego jej podatnika zapisaną
z dokładnością do 2 miejsc dziesiętnych, np.:
195.67
0.00
-312.50
Kwoty rozliczeń mogą być liczbami dodatnimi (niedopłaty podatku), ujemnymi (nadpłaty) lub
zerami (podatek rozliczony). Należy wydrukować do pliku "wyniki.txt" listę zawierającą dane
podatników wraz z odpowiadającymi im kwotami rozliczenia, uporządkowaną malejąco wg
nazwiska i dalej imienia podatnika, w następującym formacie (kolejne linie):
Nazwisko
Imię
NIP (numer identyfikacji podatkowej)
Kwota rozliczenia (zaokrąglona do liczby całkowitej)
<pusta linia>
Wymagania formalne:
Program powinien być zapisany w trzech plikach: kontener.h, dane.h i glowny.cpp (wolno rozbić
kontener na kontener.h i kontener.cpp, podobnie z dane.h i dane.cpp).
W pliku dane.h należy umieścić strukturę implementującą dane przetwarzane w programie,
przechowywane w kontenerze, wraz z odpowiednimi metodami. Tu powinny znaleźć się też
wszystkie pomocnicze funkcje, sprawdzające poprawność danych (na przykład poprawność numeru
NIP). Nie należy umieszczać w tym pliku funkcji formatujących dane do wydruku, ani żadnych
innych funkcji używających operacji wejścia-wyjścia.
W pliku kontener.h należy umieścić strukturę odpowiadającą użytemu abstrakcyjnemu typowi
danych. Można użyć szablonu lub konkretnej struktury z typem elementu odpowiadającym
strukturze zbudowanej w pliku dane.h. Należy umieścić w kontenerze i implementować tylko te
metody, które będą używane w programie głównym. Implementacja nie może zależeć od typu
elementu, powinna działać tak samo po zmianie tego typu na jakikolwiek inny. Nie może też być tu
żadnych operacji wejścia wyjścia ani formatowania wydruku kontenera.
W pliku glowny.cpp umieszczamy program główny korzystający z plików kontener.h i dane.h oraz
funkcje formatujące wydruk i inne funkcje korzystające z operacji wejścia-wyjścia.
Niedozwolone jest korzystanie z kontenerów i algorytmów z biblioteki standardowej C++.
Zapisu do pliku wynikowego nie wolno rozpocząć przed odczytaniem całości plików
wejściowych.
Dodatkowe punkty:
Za obsługę wejścia odporną na błędy użytkownika i za poprawne komentarze, w tym w
bibliotekach pomocniczych: cel funkcji, warunki wstępne, warunki końcowe, sytuacje wyjątkowe
i ewentualnie zwracany wynik, przyznawane będą dodatkowe punkty. Obsługa wejścia odporna na
błędy użytkownika powinna wyglądać następująco:
• w przypadku gdy niepoprawne są dane podatnika (czyli nieprawidłowość wystąpiła w pliku
podatnicy.txt), podatnik ten nie jest wpisywany do plik wynikowego, a odpowiadająca mu
linia w pliku rozliczenia.txt jest pomijana,
• w przypadku gdy dane podatnika są poprawne, a niepoprawna jest kwota rozliczenia (czyli
nieprawidłowość wystąpiła w pliku rozliczenia.txt), podatnik jest wpisywany do pliku
wynikowego, przy czym zamiast kwoty rozliczenia pojawia się adnotacja „

DOWERYFIKACJI”.
Kolejne punkty podwyższające ocenę można uzyskać zapewniając w programie obsługę
nieograniczonej liczby podatników zapisanych w plikach wejściowych oraz obsługę wielu imion
podatników podanych z odstępami w linii za nazwiskiem.
Dodatkowe punkty będą również przyznane za weryfikację poprawności numeru NIP. Ostatnia,
dziesiąta cyfra NIP jest cyfrą kontrolną obliczaną według poniższego algorytmu:
1. Pomnożyć każdą z pierwszych dziewięciu cyfr odpowiednio przez wagi: 6, 5, 7, 2, 3, 4, 5, 6, 7.
2. Zsumować wyniki mnożenia.
3. Obliczyć resztę z dzielenia przez 11 – powinna być ona zgodna z cyfrą kontrolną.
NIP jest tak generowany, aby nigdy w wyniku tego dzielenia nie wyszła liczba 10.

a to moje rozwiązanie

nip.h

#ifndef NIP_H_INCLUDED
#define NIP_H_INCLUDED
#include<iostream>
#include<fstream>
#include<sstream>
#include<cstdlib>
#include<exception>
#include<stdexcept>
using namespace std;
struct Podatnik
{
private:
    string nazwisko;
    string imie;
    string NIP;
    string kwota;
public:
    Podatnik(string naz=" ",string im=" ",string p=" ",string k="0.0")
    {
        nazwisko=naz;
        imie=im;
        NIP=p;
        kwota=k;
    }
    void wstawPodatnika(string a,string b,string c,string d)
    {
        nazwisko=a;
        imie=b;
        NIP=c;
        kwota=d;
    }
    void wypiszPodatnika()
    {
        cout<<imie<<" "<<nazwisko<<" "<<NIP<<" "<<kwota<<" ";
    }
    void zapisDoPliku()
    {
        bool czyPoprawne=false;
        for(int i=0;i<2;i++)
        {
            if(czyPoprawne==true)
            {
                string a="podatnicy.txt";
                fstream plik;
                plik.open(a.c_str(),ios::out|ios::app);
                plik<<imie<<" "<<nazwisko<<" "<<NIP<<endl;
                plik.close();
            }
            if(kwota[i]<0)
            {
                string a="rozliczenia.txt";
                fstream plik;
                plik.open(a.c_str(),ios::out|ios::app);
                plik<<"Do weryfikacji: "<<kwota<<endl;
                plik.close();
            }
        }
    }
};
struct Lista{
private:
    struct Node{
        Podatnik dane;
        Node*nast;
        Node(Podatnik d,Node*N=nullptr)
        {
           dane=d;
           nast=N;
        }
    };
    Node*pocz;
    int ileJest;
public:
    Lista()
    {
        pocz=nullptr;
        ileJest=0;
    }
    ~Lista()
    {
        Node*nowy=pocz;
        while(nowy!=nullptr)
        {
            Node*szuk;
            szuk=nowy->nast;
            delete nowy;
            nowy=szuk;
        }
    }
    void wypisz()
    {
        Node*nowy=pocz;
        while(nowy!=nullptr)
        {
            nowy->dane.wypiszPodatnika();
            nowy=nowy->nast;
        }
    }
    void wstaw(Podatnik p)
    {
        Node*nowy;
        nowy=new Node(p);
        if(pocz==nullptr)
        {
            pocz=nowy;
            return;
        }
        else
        {
            Node*szuk=pocz;
            while(szuk->nast!=nullptr)
            {
                szuk=szuk->nast;
            }
            szuk->nast=nowy;
        }
        ileJest++;
    }
    void zapisz()
    {
        Node*nowy=pocz;
        while(nowy!=nullptr)
        {
            nowy->dane.zapisDoPliku();
            nowy=nowy->nast;
        }
    }
};
#endif // NIP_H_INCLUDED

main.cpp

#include"nip.h"
#include<iostream>
#include<fstream>
#include<sstream>
#include<cstdlib>
#include<exception>
#include<stdexcept>
#include<string>
using namespace std;
bool sumaKontrolna(string nip)
{
    int pomoc=0,suma=0;
    int pomocnicza[9]={6, 5, 7, 2, 3, 4, 5, 6, 7};
    for(int i=0;i<=9;i++)
    {
        pomoc=nip[i]*pomocnicza[i];
        suma+=pomoc;
        pomoc=0;
    }
    if(suma%11!=10)
    {
        return true;
    }
    else
    {
        return false;
    }
}
class Error{
public: string co;
};
class ErrorNIP{
public:string co;
};
class ErrorNaz{
public: string co;
};
class ErrorIm{
public: string co;
};
class Errorkwota
{
    public:string co;
};
int main()
{
    string nazwa;
    cout<<"Podaj nazwe pliku: "<<endl;
    cin>>nazwa;

    Podatnik p;
    Lista l;

    try{
        ifstream plik;
        plik.open(nazwa.c_str(), ios::in);
        if(!plik.good())
        {
            throw logic_error("Plik nie dziala");
        }
        string linia;
        while(getline(plik,linia))
        {
            try{
                int wartosc;
                if(linia.length()<=11)
                {
                    Error e;
                    e.co=linia;
                    throw e;
                }
                while((wartosc = linia.find('-'))!=-1)
                {
                    linia.erase(wartosc,1);
                }
                string a = linia.substr(11,linia.length());
                string b = linia.substr(5,linia.length());
                string c = linia.substr(0,10);
                string d = linia.substr(linia.length());
                if(c.length()<10 || c.length()>10)
                {
                    ErrorNIP e;
                    e.co = linia;
                    throw e;
                }
                for(int i=0;i<=9;i++)
                {
                    if(c[i]<'0' || c[i]>'9')
                    {
                        ErrorNIP e;
                        e.co = linia;
                        throw e;
                    }
                }
                if(sumaKontrolna(c)==false)
                {
                    ErrorNIP e;
                    e.co = linia;
                    throw e;
                }
                if(d.length()<-1)
                {
                    Errorkwota e;
                    e.co = linia;
                    throw e;
                }
                p.wstawPodatnika(a,b,c,d);
                l.wstaw(p);
            }
            catch(Error const &e)
            {
                cout<<"Blad"<<e.co<<endl;
            }
            catch(ErrorNaz const &e)
            {
                cout<<"Nazwisko sie nie zgadza"<<e.co<<endl;
            }
            catch(ErrorIm const &e)
            {
                cout<<"imie sie nie zgadza"<<e.co<<endl;
            }
            catch(ErrorNIP const &e)
            {
                cout<<"NIP jest niepoprawny "<<e.co<<endl;
            }
            catch(Errorkwota const &e)
            {
                cout<<"Do weryfikacji "<<e.co<<endl;
            }
        }
        l.wypisz();
        l.zapisz();
        plik.close();
    }
    catch(exception &e)
    {
        cout<< e.what()<<endl;
    }
    return 0;

}

 

3 odpowiedzi

+1 głos
odpowiedź 19 czerwca 2023 przez j23 Mędrzec (194,920 p.)
edycja 22 czerwca 2023 przez j23

Skoro rekordy w pliku są w postaci:

  • NIP (numer identyfikacji podatkowej)
  • Nazwisko Imię
  • pusta linia

to nie wiem, dlaczego się dziwisz, że Ci to nie działa, przecież w pętli czytasz od razu numer NIP i w sumie nic więcej.

Podziel kod na funkcje:

  • czytającą rekord
  • sprawdzającą poprawność NIP-u
  • czytającą całą bazę do listy.

Podawanie flagi std::ios::in strumieniowi std::ifstream jest zbędne.

komentarz 20 czerwca 2023 przez martinez369 Początkujący (460 p.)
#include"nip.h"
#include<iostream>
#include<fstream>
#include<sstream>
#include<cstdlib>
#include<exception>
#include<stdexcept>
#include<string>
using namespace std;
bool sumaKontrolna(string nip)
{
    int pomoc=0,suma=0;
    int pomocnicza[9]={6, 5, 7, 2, 3, 4, 5, 6, 7};
    for(int i=0;i<=9;i++)
    {
        pomoc=nip[i]*pomocnicza[i];
        suma+=pomoc;
        pomoc=0;
    }
    if(suma%11!=10)
    {
        return true;
    }
    else
    {
        return false;
    }
}
class ErrorNIP{
public:string co;
};
class ErrorNaz{
public: string co;
};
class ErrorIm{
public: string co;
};
class Errorkwota
{
    public:string co;
};
int main()
{
    string nazwa;
    cout<<"Podaj nazwe pliku: "<<endl;
    cin>>nazwa;

    Podatnik p;
    Lista l;

    try{
        ifstream plik;
        plik.open(nazwa.c_str(), ios::in);
        if(!plik.good())
        {
            throw logic_error("Plik nie dziala");
        }
        string linia;
        while(getline(plik,linia))
        {
            try{
                int wartosc;
                string imie, nazwisko, nip, kwota;
                stringstream liniaStream(linia);
                liniaStream >> nip;
                getline(liniaStream, nazwisko, ' ');
                getline(liniaStream, imie);
                getline(plik, kwota);
                while((wartosc = linia.find('-'))!=-1)
                {
                    linia.erase(wartosc,1);
                }
                if(liniaStream.fail() || imie.empty())
                {
                    ErrorIm e;
                    e.co=linia;
                    throw e;
                }
                else if(liniaStream.fail() || nazwisko.empty())
                {
                    ErrorNaz e;
                    e.co=linia;
                    throw e;
                }
                if(nip.length()<10 || nip.length()>10)
                {
                    ErrorNIP e;
                    e.co = linia;
                    throw e;
                }
                for (int i=0; i<=9; i++)
                {
                    if(nip[i]<'0' || nip[i]>'9')
                    {
                        ErrorNIP e;
                        e.co = linia;
                        throw e;
                    }
                }
                if(sumaKontrolna(nip)==false)
                {
                    ErrorNIP e;
                    e.co = linia;
                    throw e;
                }
                double kwotaRozliczenia = stod(kwota);
                if(kwotaRozliczenia<0.0)
                {
                    Errorkwota e;
                    e.co = linia;
                    throw e;
                }
                p.wstawPodatnika(nazwisko,imie,nip,kwota);
                l.wstaw(p);
            }
            catch(ErrorNaz const &e)
            {
                cout<<"Nazwisko sie nie zgadza"<<e.co<<endl;
            }
            catch(ErrorIm const &e)
            {
                cout<<"imie sie nie zgadza"<<e.co<<endl;
            }
            catch(ErrorNIP const &e)
            {
                cout<<"NIP jest niepoprawny "<<e.co<<endl;
            }
            catch(Errorkwota const &e)
            {
                cout<<"Do weryfikacji "<<e.co<<endl;
            }
        }
        l.wypisz();
        l.zapisz();
        plik.close();
    }
    catch(exception &e)
    {
        cout<< e.what()<<endl;
    }
    return 0;

}

main.cpp

#ifndef NIP_H_INCLUDED
#define NIP_H_INCLUDED
#include<iostream>
#include<fstream>
#include<sstream>
#include<cstdlib>
#include<exception>
#include<stdexcept>
using namespace std;
struct Podatnik
{
private:
    string nazwisko;
    string imie;
    string NIP;
    string kwota;
public:
    Podatnik(string naz=" ",string im=" ",string p=" ",string k="0.0")
    {
        nazwisko=naz;
        imie=im;
        NIP=p;
        kwota=k;
    }
    void wstawPodatnika(string a,string b,string c,string d)
    {
        nazwisko=a;
        imie=b;
        NIP=c;
        kwota=d;
    }
    void wypiszPodatnika()
    {
        cout<<imie<<" "<<nazwisko<<" "<<NIP<<" "<<kwota<<" ";
    }
    void zapisDoPliku()
    {
        int kontrolka = 0;
        for (int i=0; i<3; i++)
        {
            kontrolka = kontrolka + (NIP[i] - '0');
            if (kontrolka == 0 )
            {
                string a = "podatnicy.txt";
                fstream plik;
                plik.open( a.c_str(), ios::out | ios::app );
                plik << nazwisko << " " << imie << " " << NIP<<" "<<kwota<<endl;
                plik.close();
            }
            else if (kontrolka == 1)
            {
                string b = "rozliczenia.txt";
                fstream plik;
                plik.open( b.c_str(), ios::out | ios::app );
                plik << kwota << endl;
                plik.close();
            }
            else if (kontrolka == 2)
            {
                string c = "wynik.txt";
                fstream plik;
                plik.open( c.c_str(), ios::out | ios::app );
                plik << nazwisko << " " << imie << " " << NIP<<endl;
                plik.close();
            }
        }
    }
};
struct Lista{
private:
    struct Node{
        Podatnik dane;
        Node*nast;
        Node(Podatnik d,Node*N=nullptr)
        {
           dane=d;
           nast=N;
        }
    };
    Node*pocz;
    int ileJest;
public:
    Lista()
    {
        pocz=nullptr;
        ileJest=0;
    }
    ~Lista()
    {
        Node*nowy=pocz;
        while(nowy!=nullptr)
        {
            Node*szuk;
            szuk=nowy->nast;
            delete nowy;
            nowy=szuk;
        }
    }
    void wypisz()
    {
        Node*nowy=pocz;
        while(nowy!=nullptr)
        {
            nowy->dane.wypiszPodatnika();
            nowy=nowy->nast;
        }
    }
    void wstaw(Podatnik p)
    {
        Node*nowy;
        nowy=new Node(p);
        if(pocz==nullptr)
        {
            pocz=nowy;
            return;
        }
        else
        {
            Node*szuk=pocz;
            while(szuk->nast!=nullptr)
            {
                szuk=szuk->nast;
            }
            szuk->nast=nowy;
        }
        ileJest++;
    }
    void zapisz()
    {
        Node*nowy=pocz;
        while(nowy!=nullptr)
        {
            nowy->dane.zapisDoPliku();
            nowy=nowy->nast;
        }
    }
};
#endif // NIP_H_INCLUDED

nip.h

Poprawiłem co nieco ale nadal występuję błąd że jest nazwisko nie poprawne w pliku gdzie może być błąd

1
komentarz 20 czerwca 2023 przez j23 Mędrzec (194,920 p.)

Czekaj, czekaj. W opisie masz dwa pliki - jeden z listą podatników, drugi - listą rozliczeń. Czyli czytanie podatników może wyglądać tak:

std::istream& readPodatnik(std::istream& p_is, std::istream& r_is, Podatnik& p)
{
    string imie, nazwisko, nip, kwota;

    std::getline(p_is >> std::ws, nip);
    std::getline(p_is >> nazwisko >> std::ws, imie);
    r_is >> kwota;
    if(!checkNIP(nip)) nip = "";
    p = Podatnik(nazwisko, imie, nip, kwota);
    return p_is;
}

...

    Podatnik p;
    std::ifstream p_is("podatnicy.txt");
    std::ifstream r_is("rozliczenia.txt");
    
    while (readPodatnik(p_is, r_is, p)) {
        if(p.get_NIP().empty()) continue; // nieprawidłowy nip, pomijamy padatnika
        l.wstaw(std::move(p));
    }

Klasa Podatnik tak powinna wyglądać (zgodnie z zasadą pojedynczej odpowiedzialności):

struct Podatnik
{
    Podatnik() = default;
    Podatnik(std::string nazwisko_, std::string imie_, std::string NIP_, std::string kwota_)
        :nazwisko(std::move(nazwisko_)),
        imie(std::move(imie_)),
        NIP(std::move(NIP_)),
        kwota(std::move(kwota_))
    {}
    
    std::string get_nazwisko() const { return nazwisko; }
    std::string get_imie() const { return imie; }
    std::string get_NIP() const { return NIP; }
    std::string get_kwota() const { return kwota; }    

private:
    std::string nazwisko;
    std::string imie;
    std::string NIP;
    std::string kwota;
};

 

0 głosów
odpowiedź 21 czerwca 2023 przez TOWaD Mądrala (6,000 p.)
edycja 21 czerwca 2023 przez TOWaD

Jak nie można std::kontenerów to i string odpada, to może użyć Qstrin  Qvector itd : ). Dziwnie C++ wygląda bez std::.

Ale tak poważnie to, mi się wydaje ze trochę nie na temat ten twój program. 

kontener.h wygląda jak by miał być templatką (szablonem).

Implementacja nie może zależeć od typu
elementu, powinna działać tak samo po zmianie tego typu na jakikolwiek inny.

Choć wcześniej jest napisane

Można użyć szablonu lub konkretnej struktury z typem elementu odpowiadającym
strukturze zbudowanej w pliku dane.h

Tak wiec nie dokładnie wiadomo czy musi być szablon czy nie.

własny vector na przykład coś takiego. Edit lub z forum pasji informatyki

Vector, bo chyba łatwiej posortować niż listę.np quick sort. Bo trzeba posortować przed wysłaniem do pliku, względem kwoty.

Te moje moje linki to tylko takie przykładowe można wygooglować inne.

W pliku glowny.cpp umieszczamy program główny korzystający z plików kontener.h i dane.h oraz
funkcje formatujące wydruk i inne funkcje korzystające z operacji wejścia-wyjścia.

Może to tu trzeba przeciążyć operatory.

https://en.cppreference.com/w/cpp/language/operators, lub na polskich stronach

std::ostream& operator<<(std::ostream& os, const T& obj)
{
    // write obj to stream
    return os;
}
 
std::istream& operator>>(std::istream& is, T& obj)
{
    // read obj from stream
    if (/* T could not be constructed */)
        is.setstate(std::ios::failbit);
    return is;
}

Może za tydzień, jakiś przykład mi się uda wyklepać(albo i nie)

–1 głos
odpowiedź 21 czerwca 2023 przez infinityhost Użytkownik (780 p.)
edycja 21 czerwca 2023 przez infinityhost

Ogólnie kod jest elegancki, używasz listy łączonej. Jest wszystko ok. Jak zamienisz Podatnik na *Podatnik - będzie rewelka.

To ma tak  być ? Node*nowy=pocz;" nie widzę spacji.

Pamiętaj, że C++ ma typ void.

Wklejałeś kod do AI? On nie patrzy na jezyk w kodzie po prostu to sprawdza.

"Vector, bo chyba łatwiej posortować niż listę.np quick sort. Bo trzeba posortować przed wysłaniem do pliku, względem kwoty." - najprostsze sortowanie to 2 pętle jedna w drugiej. Banał.

"Jak nie można std::kontenerów to i string odpada" - żaden problem , zamieniasz string na char* ( tak jak Podatnik na *Podatnik)

Ja jak bym się nudził to dodał kompresję struktury i dopasowanie do rozmiaru bitowego (może i własny typ danych - nie bajtowy)

Pracodawcy chyba lubią taki estetyczny elegancki kod, ale poza nimi na świecie są też zwykli ludzie i klienci. 

Potrzeb świata nie zaspokoisz tak skupiając się na każdej linijce, bo to jest czas, to czego jeszcze nie kupisz.

1
komentarz 21 czerwca 2023 przez j23 Mędrzec (194,920 p.)

Jak zamienisz Podatnik na *Podatnik - będzie rewelka.

A po co?

"Jak nie można std::kontenerów to i string odpada" - żaden problem , zamieniasz string na char* ( tak jak Podatnik na *Podatnik)

IMO tu raczej chodzi o kontenery typu std::vector czy std::list. std::string traktowałbym jako typ do przechowywania tekstu.

Podobne pytania

0 głosów
0 odpowiedzi 209 wizyt
pytanie zadane 6 maja 2020 w C i C++ przez Rajzok Początkujący (390 p.)
0 głosów
1 odpowiedź 124 wizyt
pytanie zadane 15 maja 2016 w C i C++ przez DragonCoder Nałogowiec (36,500 p.)
0 głosów
1 odpowiedź 740 wizyt

92,634 zapytań

141,505 odpowiedzi

319,883 komentarzy

62,015 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...