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

polimorfizm klasa

VPS Starter Arubacloud
0 głosów
217 wizyt
pytanie zadane 13 sierpnia 2020 w C i C++ przez lujasjeden Użytkownik (860 p.)

Czy moge miec w programie wiecej niz 1 klase podstawowa abstrakcyjna? 

W glowie mam program ktory bedzie pobieral od uzytkownika wielomian/ciąg/logarytm i moze w przyszlosci jeszcze inne wyrazenia (algebraiczne/arytmetyczne (jakie?)) a potem wykonywal na nich jakies operacje: dodawanie, odejmowanie, mnozenie, dzielenie, liczenie granicy, okreslanie monotonicznosci itd.

Zalozmy, ze stworze podstawowa klase abstrakcyjna:

class wyrazenieAlgebraiczne
{
    virtual void wczytaj()=0;
    virtual void wypisz()=0;
}

z tej klasy beda dziedziczyc np. class wielomianWx; class wielomianPx (on tez bedzie dziedziczyl po wielomianWx, bo beda mialy wlasciwie te same atrybuty), class ciagAn, ciagBn, ciagCn (tez pewnie beda dziedziczyc po sobie, ale tego jeszcze nie pisalem).

No i pytanie brzmi czy funkcje z operacjami (funkcjami) takimi jak dodawanie(), odejmowanie(), mnozenie(), dzielenie(), dac rowniez do klasy podstawowej wyrazenieAlgebraiczne, czy moze stworzyc druga klase podstawowa abstrakcyjna:

class operacje
{
    virtual void dodawanie()=0;
    virtual void odejmowanie()=0;
​    virtual void mnozenie()=0;
    virtual void dzielenie()=0;
    virtual void znajdzGranice()=0;
    virtual void okreslMonotonicznosc()=0;
//itd...
}

Wydaje mi sie, ze danie tego do jednej klasy podstawowej to moze byc troche balagan, aczkolwiek nigdy nie pisalem nic z wykorzystaniem polimorfizmu, wlasciwie to pierwszy kod, ktory pisze objektowo.

tldr

Czy moge miec w kodzie wiecej niz 1 klase podstawowa abstrakcyjna?

1
komentarz 13 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)
Albo klasa jest podstawowa, albo klasa jest abstrakcyjna... Multidziedziczenie jest strzałem w kolano w przeważającej ilości sytuacji. W tej też takim będzie. Jakie widzisz plusy rozwiązania tego problemu dzięki "interfejsom"?
komentarz 13 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)
Z filmu Miroslawa Zelenta zrozumialem ze klasa podstawowa abstrakcyjna to ta ktora ma funkcje virtual i jest tylko po to aby stworzyc wskaznik, nie rozumiem ostatniego zdania, zapomnialem zaznaczyc, ze jestem poczatkujacy i wielu rzeczy nie umiem.

Multidziedziczenie czyli dziedziczenie np z dwoch klas wirtualnych? (nie wiem) Czyli u mnie np klasa wielomianWx odziedziczylaby po klasie wyrazenieAlgebraiczne funkcje wczytaj() oraz wypisz() i po klasie operacje dodawanie(), odejmowanie(), mnozenie() i dzielenie(). Mowisz ze jest to strzal w kolano (?), czyli w takim razie funkcje z klasy operacje dac do klasy wyrazenieAlgebraiczne?
komentarz 13 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)
Przeczytaj o problemie diamentu w C++.

Abstrahując od sensowności tego rozwiązania pod względem czysto programistycznym. Twoje założenia co do możliwej funkcjonalności będą błędne, ponieważ na ciągach nie jesteś w stanie wykonać tych operacji(jedyna możliwość, to na uzyskanym wyniku).
Tak samo metoda "znajdzGranice" jest bardzo specyficzną operacją matematyczną, która kompletnie nie ma nic wspólnego z "operacjami" arytmetycznymi. Doczytaj w kwestiach algebry liniowej, oraz analizy matematycznej, by lepiej pojąć temat od kwestii czysto domenowej.
komentarz 13 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)
ok, dalem przyklady no zalozmy ze beda tylko dodawanie odejmowanie mnozenie i dzielenie (to juz moge zrobic w wielomianach, logarytmach), kod w tym momencie nie musi byc czysty, chce sie nauczyc polimorfizmu, zapewne i tak bede zmienial rzeczy pozniej kiedy bede umial juz wiecej, chcialem zapytac czy zrobic to w 1 czy 2 klasach podstawowych.

A funkcje pobierz i wypisz moga odziedziczyc wszystkie klasy ktore wypisalem.
komentarz 13 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)
Tak jak pisałem wcześniej. Tworzenie klasy dajmy na to Logarytm jako klasę podstawową, która będzie implementowała dwa interfejsy jest jest bez sensu, bo nie skorzystasz z możliwości jaki daje dynamiczny polimorfizm.
komentarz 13 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)
A klasa podstawowa to nie bylaby wyrazenieAlgebraiczne oraz operacje, a logarytm to klasa pochodna?

W takim razie moglbys zaproponowac jakies rozwiazanie?
komentarz 13 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)
Kompozycja. Osobna klasa do wczytywania, osobna do liczenia itd..
komentarz 13 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)

no tak chyba chcialem zrobic, czy nie?

class wyrazenieAlgebraiczne
{
    virtual void wczytaj()=0;
    virtual void wypisz()=0;
}

to jest klasa z ktorej beda dziedziczyly klasy takie jak wielomianWx, wielomianPx, ciągAn, ciągBn, ciągCn

class operacje
{
    virtual void dodawanie()=0;
    virtual void odejmowanie()=0;
​    virtual void mnozenie()=0;
    virtual void dzielenie()=0;
    virtual void znajdzGranice()=0;
    virtual void okreslMonotonicznosc()=0;
//itd...
}

to jest klasa z ktorej beda dziedziczyly poszczegolne funkcje klasy takie jak wielomianWx, wielomianPx, ciągAn, ciągBn, ciągCn

I zalozmy ze wielomianWx odziedziczy od wyrazenieAlgebraiczne funkcje wczytaj i wypisz, klasa menuWielomiany odziedziczy od operacje funkcje takie jak dodawanie() odejmowanie() mnozenie() dzielenie()

Tylko nie jestem pewny czy moge tak zrobic ze jeszcze wielomianPx odziedziczy od wielomianWx jego atrybuty i jeszcze funkcje wirtulane od wyrazeniaAlgebraiczne: wczytaj() i wypisz()

No i wywolanie w mainie np kalkulatora wielomianow tak by wygladalo wtedy:

//Wlasciwie to nie wiem czy tak to bedzie wygladalo, no nigdy nie //pisalem czegos takiego,
//zgaduje tylko, ale mam nadzieje ze rozumiesz o co mi chodzi nawet //jesli nie jest to
//poprawna skladnia

wyrazenieAlgebraiczne *wsk;
wsk = &Wx;


wielomianWx Wx()
wsk->wczytaj;
wsk->pokaz;
wsk = &Px;
wielomianPx Px()
wsk->wczytaj;
wsk->pokaz;

menuWielomiany *wsk;
wsk = &mW; 
menuWielomiany mW()
mW->menu
//tutaj byloby menu ktore wygladalo by mniej wiecej tak z tym ze //pewnie by sie roznilo to
//trescia troche, nie wiem czy wtedy w body tej funkcji menu tez by //sie uzywalo wskaznikow,
//juz pozno i ciezko mi sie mysli w tym momencie plus bardzo daleko //wybieglem w glowie
//bez kodu, ale daje ci zarys o co mi chodzi

void menuWielomiany::menu()
{
    cout<<"Main menu"<<endl;
    cout<<"---------------------"<<endl;
    cout<<"1.Addition"<<endl;
    cout<<"2.Subtraction"<<endl;
    cout<<"3.Multiplication"<<endl;
    cout<<"4.Division"<<endl;
    cout<<"5.Exit"<<endl;
    cout<<endl;
    cout<<"Choose an operation: ";
    cin>>choice;
    while (cin.fail())
    {
        cout<<"There is no such option"<<endl;
        cin.clear();
        cin.ignore(1000, '\n');
        cin>>choice;
    }
    cout<<endl;

    switch(choice)
    {
    case 1:
        {
            cout<<"W(x)+P(x) = ";
            addition();
        }
        break;
    case 2:
        {
            cout<<"W(x)-P(x) = ";
            subtraction();
        }
        break;
    case 3:
        {

        }
        break;
    case 4:
        {

        }
        break;
    case 5:
        {
            cout<<"Goodbye";
            exit(0);
        }
        break;
    default:
        {
            cout<<"There is no such option";
        }
        break;
    }

 

komentarz 13 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)

No niezupełnie. Twoje klasy, to c++ wersje interfejsów. Osobiście nie widzę sensu stosowania ich akurat tutaj. Widzę bardziej to w takiej postaci:

class Ciag
{
    //metody
};

class CiagArytmetyczny : public Ciag
{
    //implementacja metod
};

class CiagGeometryczny : public Ciag
{
    //implementacja metod
};

Musisz popracować nad semantyką używanych zdań.
Wyrażenie algebraiczne, to zdanie popranie ułożone według języka algebry. 
WielomianWx jest tak samo zbyt ogólny, wielomiany rozróżniamy "jak już" po jego stopniu.

komentarz 13 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)
tak stopien podaje uzytkownik w metodzie wczytaj, tak jak ty zrobiles no to tez tak myslalem ale wtedy pomyslalem, ze chce zrobic wielomiany, wiec musialbym zrobic to samo dla wielomianow i potem to samo dla np logarytmow i moze jeszcze czegos, wlasnie przed poznaniem polimorfizmu tak dokladnie mialem
komentarz 13 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)
Tylko, że to właśnie jest polimorfizm. Klasa bazowa Ciag i dwie pochodne.
komentarz 13 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)

mam tak:

class Wx
{
protected:

string userStringNum;
int degree;
int helper;
float *coefficients;

public:

void gahter();
void show();
void isInteger();
void isFloat();
}

class Px :public Wx
{

}

 

komentarz 13 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)
a no dobra to przepraszam w takim razie, no ale lepiej to chyba nazwac ogolniej a nie ciag, zeby mogly dziedziczyc jeszcze wielomiany czy logarytmy?
komentarz 13 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)
Podejście obiektowe pozwala na stosunkowo wysoki poziom abstrakcji, ale łatwo przeholować. Nazwa klasy "operacje" jest mało mówiąca. Zrobisz jak uważasz, tylko w mojej ocenie nie ma to sensu, by po klasie, która jest odpowiedzialna za ciągi, dziedziczyły jeszcze wielomiany, czy logarytmy.
komentarz 13 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)
z tym ze wtedy taki np wielomianPx dziedziczylby funkcje wirutalne z klasy wyrazenieAlgebraiczne wczytaj() wypisz(), atrybuty od wielomianWx oraz funkcje wirtualne od klasy operacje

a to chyba juz problem, czy nie?
komentarz 13 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)
hmmm ale chyba nie musze im wszystkiego posylac, wszystkich funkcji?

Tylko odpowiednio dla wielomianow poleci z operacje dodawanie() odejmowanie() mnozenie() dzielenie(), dla ciagow znajdzGranice() oraz zbadajMonotonicznosc, a dla logarytmow tez dodawanie() odejmowanie() mnozenie() dzielenie(), no a z wyrazenieAlgebraiczne wczytaj() wypisz() skorzystaja wszyscy
komentarz 13 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)
To inaczej, zacznij od sposobu w jaki byś chciał użyć tych klas. Może TDD? Testy na pewno rozjaśnią implementację.
Po za tym co do ciągów, logarytmów, czy innych działań. Są pomiędzy nimi różnice, które uniemożliwią wykorzystanie w pełni polimorfizmu. Zastanów się, czy jest na pewno potrzebny, czy chcesz go po prostu wykorzystać.
komentarz 13 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)
wlasnie chce go wykorzystac, nie wiem czy jest to najoptymalniejsze tak naprawde, dla kompromisu moge skorzystac z polimorfizmu tylko dla metod wypisz i wczytaj
komentarz 13 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)

Tylko odpowiednio dla wielomianow poleci z operacje dodawanie() odejmowanie() mnozenie() dzielenie(), dla ciagow znajdzGranice() oraz zbadajMonotonicznosc, a dla logarytmow tez dodawanie() odejmowanie() mnozenie() dzielenie(), no a z wyrazenieAlgebraiczne wczytaj() wypisz() skorzystaja wszyscy

Przy interfejsach musisz zaimplementować wszystkie metody. 

komentarz 13 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)
Kompozycja ponad dziedziczenie. Będzie prościej.
komentarz 13 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)
co do TDD, wygooglowalem, nie ogarniam jeszcze na tyle chyba, co do kompozycja ponad dziedziczenie co masz na mysli?
komentarz 13 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)
Zamiast dziedziczyć(na siłę), utwórz osobne klasy, które będą odpowiedzialne za wczytywanie, czy wyświetlanie i użyj ich jak funkcji w innych klasach.
komentarz 14 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)

nie wiem czy przez to ze juz jestem zmeczony czy nie rozumiem ale nie podoba mi sie to,

a moglbys odpowiedziec czy uzycie polimorfizmu tylko w ten sposob bedzie mialo jakies wady?:

class wypiszWczytaj
{
public:
virtual void wypisz();
virtual void wczytaj();
virtual void isInteger();
}

class wielomianWx :public wypiszWczytaj
{
protected:
string userStringNum;
int degree;
int helper;
int *coefficients;
}

class wielomianPx :public wielomianWx  
//i teraz czy zeby odziedziczyc jeszcze metody
//wypisz() wczytaj() isInteger() potrzebuje dodac :public wypiszWczytaj ?
{
}
//basically tak
class wielomianPx :public wielomianWx
//czy
class wielomianPx :public wielomianWx :public wczytajWypisz

//zeby wielomianPx i wielomianWx mialo wszystko takie samo


//no i teorytycznie moglbym wszystko wrzucic w klase wypiszWczytaj tylko ze wtedy
//byloby to nierozszerzalne dla ciagow czy logarytmow bo nie chcialbym dziedziczyc np
//int degree dla ciagow

 

komentarz 14 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)
O ile nie będzie nigdzie później problemu, że dziedziczysz po klasie, która już wcześniej była dziedziczona, to raczej nie. Wątpię tylko w czytelność tego kodu. Czemu masz wielomianPx i wielomianWx? Albo ja nie rozumiem Twojego konceptu, albo Ty nie rozumiesz zasad w matematyce. Tworzysz klasę Wielomian, przeciążasz dla niej znaki i tyle.
komentarz 14 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)

o przeciazeniach tylko slyszalem ale nie poslugiwalem sie nigdy juz ci dam caly kod zebys zrozumial o co mi chodzi

result.h

#include <iostream>

using namespace std;

class Result
{
private:
    string userStringNum;
    int dWx; //degree of polynomial W(x)
    int dPx; //degree of polynomial P(x)
    float *RWxPx; //coefficients of result
    float *cWx; //coefficients of W(x)
    float *cPx; //coefficients of P(x)
    int dWxPx; //degree of result
    int Helper; //helping variable for showing results
    int choice; //user's choice

public:

    void gatherWxPx(); //gathering polynomial W(x) from user
    Result(int=0, int=0);  //constructor
    ~Result();         //destructor

    void addition(); //adding polynomials
    void subtraction(); //subtracting polynomials
    void multiplication(); //multiplying polynomials
    void division(); //dividing polynomials
    void showResult(); //output result after calculation
    void menu(); //menu
    void isInteger(int &d); //checking if user's input is an integer
};

gatherWxPx

#include <iostream>
#include "result.h"

using namespace std;


Result::Result(int Wx, int Px)
{
    dWx=Wx;
    dPx=Px;
}
void Result::gatherWxPx()
{
    cout<<"Input degree of polynomial W(x): ";

    isInteger(dWx);
    int HelperWx=dWx;

    cout<<"Input degree of polynomial P(x): ";

    isInteger(dPx);
    int HelperPx=dPx;

    cWx = new float [dWx+1];     //dynamically allocating arrays for W(x)

    cout<<"Input coefficients and constant of polynomial W(x): ";
    cout<<endl;

    for (int i=dWx; i>=0; i--)
    {
        cin>>cWx[i];     //gathering coefficients of W(x)
    }

    cout<<"W(x)= ";              //show W(x)
    for (int i=dWx; i>=0; i--)
    {
        if (cWx[i]>0 && i!=HelperWx)
        {
            cout<<"+";
        }
        if (cWx[i]==-1 && i!=0)
        {
            cout<<"-";
        }
        if (cWx[i]!=0)
        {
            if ((cWx[i]!=1 && cWx[i]!=-1) || i==0)
            {
                cout<<cWx[i];
            }
            if (i!=0)
            {
                cout<<"x";
            }
            if (i!=0 && i!=1)
            {
                cout<<i;
            }
        }
        else if (cWx[i]==0)
        {
            HelperWx--;
        }
        if (i<=0 && HelperWx==-1)
        {
            cout<<"0";
        }
    }

    cout<<endl;
    cout<<endl;

    cPx = new float [dPx+1];  //dynamically allocating arrays for P(x)

    cout<<"Input coefficients and constant of polynomial P(x): ";
    cout<<endl;

    for (int i=dPx; i>=0; i--)
    {
        cin>>cPx[i];      //gathering coefficients of P(x)
    }

    cout<<"P(x)= ";             //show P(x)
    for (int i=dPx; i>=0; i--)
    {
        if (cPx[i]>0 && i!=HelperPx)
        {
            cout<<"+";
        }
        if (cPx[i]==-1 && i!=0)
        {
            cout<<"-";
        }
        if (cPx[i]!=0)
        {
            if ((cPx[i]!=1 && cPx[i]!=-1) || i==0)
            {
                cout<<cPx[i];
            }
            if (i!=0)
            {
                cout<<"x";
            }
            if (i!=0 && i!=1)
            {
                cout<<i;
            }
        }
        else if (cPx[i]==0)
        {
            HelperPx--;
        }
        if (i<=0 && HelperPx==-1)
        {
            cout<<"0";
        }
    }
    cout<<endl;
    cout<<endl;

}





Result::~Result()
{
    delete [] cWx;
    delete [] cPx;
    delete [] RWxPx;
    system("cls");
}

no i np addition

#include <iostream>
#include "result.h"

using namespace std;

void Result::addition()
{
    if (dWx>=dPx)
    {
        Helper=dWx;
        dWxPx=dWx;
        RWxPx = new float [dWx+1];

        for (int i=dWx; i>dPx; i--)
        {
            RWxPx[i]=cWx[i];
        }
        for (int i=dPx; i>=0; i--)
        {
            RWxPx[i]=cWx[i]+cPx[i];
        }
    }
    else
    {
        Helper=dPx;
        dWxPx=dPx;
        RWxPx = new float [dPx+1];

        for (int i=dPx; i>dWx; i--)
        {
            RWxPx[i]=cPx[i];
        }
        for (int i=dWx; i>=0; i--)
        {
            RWxPx[i]=cWx[i]+cPx[i];
        }
    }
}

moze byc troche balagan bo to kopia na ktorej testowalem rozne rzeczy, wiec ten konstruktor moze nie miec sensu, ogolnie jest duzo rzeczy nie napisanych ale moze lepiej bedziesz mnie rozumial, nie ma tu dziedziczenia jeszcze, chcialem je dodac, no ogolnie chce jak najbardziej zoptymalizowac kod, zeby byl rozszerzalny no i zebym sie nauczyl roznych rzeczy

isInteger

#include <iostream>
#include "result.h"
#include <ctype.h> // isdigit()
#include <sstream> // stringstream
using namespace std;
void Result::isInteger(int &d)
{
    int isInt=0;
    int decimalCount=0;

    bool isIntBool=false;
    bool containsSpaces = false;

    do
    {
        getline(cin, userStringNum);

        for (int i=0; i<userStringNum.size(); i++)
        {
            if (isspace(userStringNum[i]))
                containsSpaces=true;
        }

        if (userStringNum[0] == '-')
        {
            isInt++;

            if (userStringNum[1]=='0')
                isInt=0;
        }

        if ((userStringNum[0]=='0' && isdigit(userStringNum[1])))
            isInt = 0;
        else
        {
            for (int i=0; i<userStringNum.size(); i++)
            {
                if (isdigit(userStringNum[i]))
                    isInt++;
                if (userStringNum[i]=='.')
                    decimalCount++;
            }
        }

        if (decimalCount==1)
            isInt=0;

        if (isInt==userStringNum.size() && containsSpaces==false)
        {
            stringstream str_stream_object(userStringNum);
            str_stream_object>>d;

            isIntBool=1;
        }

        else
        {
            cout<<endl;
            cout<<"Degree of polynomial has to be an integer greater than 0, try again: ";

            isIntBool=0;
            isInt=0;
            decimalCount=0;
            containsSpaces=false;
        }

    }
    while (isIntBool==0);
}

dzieki ogolnie za dotychczasowa pomoc, chcialbym sie jak najwiecej dowiedziec, ostatnie dni bardzo sie w to wciagnalem, w programowanie, chcialbym zalapac podstawy oop zeby moc pozniej albo wlasnie rozszerzac ten projekt albo trzaskac w innych projektach inne rzeczy co sie do matury bede z matmy przygotowywal tak w ramach nauki i matmy i programowania

komentarz 14 sierpnia 2020 przez tkz Nałogowiec (42,000 p.)
Dla mnie kod jest mało czytelny i chaotyczny. Nazwy mi nic nie mówią. Jest za dużo ogólników. Klasa Result tworzy i oblicza wielomiany? Mało intuicyjne.
komentarz 14 sierpnia 2020 przez lujasjeden Użytkownik (860 p.)
tak no to bedzie zmieniane, wlasnie dlatego tutaj pytam o te wszystkie rzeczy

mialem zrobic wlasnie klasy wielomianWx, wielomianPx, operacje, i wtedy wielomianPx by dziedziczyl tylko od wielomianWx, ale wtedy zobaczylem film o polimorfizmie i pomyslalem zeby rozszerzyc to jeszcze o ciagi i logarytmy, i dlatego pytam jak to najsensowniej zrobic

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
2 odpowiedzi 285 wizyt
pytanie zadane 28 marca 2017 w C i C++ przez akiihombre Początkujący (250 p.)
0 głosów
2 odpowiedzi 191 wizyt
0 głosów
1 odpowiedź 182 wizyt
pytanie zadane 17 lipca 2017 w Java przez heartagram Obywatel (1,770 p.)

92,455 zapytań

141,263 odpowiedzi

319,100 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...