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

question-closed Lekcja 6 kursu C++ YouTube [ulepszony kalkulator]

VPS Starter Arubacloud
+2 głosów
588 wizyt
pytanie zadane 12 września 2016 w C i C++ przez 4sp3ll Początkujący (410 p.)
zamknięte 16 września 2016 przez 4sp3ll

Witam,

To mój pierwszy post, więc witam serdecznie wszystkich! :)

Chciałbym ulepszyć kalkulator zamieszczony w kursie na YouTube (lekcja 6, C++ (instrukcja switch case, menu główne).

Chciałbym, między innymi, aby po wybraniu default w funkcji switch program nie resetował się całkowicie tylko po wyświetleniu napisu: "Taka opcja nie jest dostepna, wybierz ponownie klawisz z listy... " powrócił do możliwości wyboru. Domyślam się, że może być tutaj przydatna pętla, ale po długim czasie szukania rozwiązania nic działającego nie udało mi się stworzyć, proszę was o pomoc.

Jeżeli to możliwe, to proszę o podpowiedzi a nie gotowe rozwiązania. Jestem bardzo początkujący.

#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <cstdlib>

using namespace std;

float x,y;
char wybor;

int main()
{
    for(;;)
    {
    cout << "Podaj liczbe 1: ";
    cin>>x;
    cout<<endl;
    cout << "Podaj liczbe 2: ";
    cin>>y;
    cout<<endl;

    cout<<"Co chcesz zrobic z tymi liczbami?"<<endl;
    cout<<"=================================="<<endl;
    cout<<"1. Dodac"<<endl;
    cout<<"2. Odjac"<<endl;
    cout<<"3. Pomnozyc"<<endl;
    cout<<"4. Podzielic"<<endl;
    cout<<"5. Exit"<<endl;
    cout<<endl;
    cout<<"Wybierz klawisz z listy... "<<endl<<endl;
    wybor=getch();

        switch (wybor)
    {
        case '1':
            cout<<"Wynik dodawania: "<<x+y;
        break;

        case '2':
            cout<<"Wynik odejmowania: "<<x-y;
        break;

        case '3':
            cout<<"Wynik mnozenia: "<<x*y;
        break;

        case '4':
            if (y==0) cout<<"Nie dziel przez 0! ";
            else cout<<"Wynik dzielenia: "<<x/y;
        break;

        case '5':
            exit(0);
        break;

        default:
            cout<<"Taka opcja nie jest dostepna"<<endl;
            cout<<"Wybierz ponownie klawisz z listy... "<<endl<<endl;
        break;
    }

    cout<<endl;
    cout<<"Nacisnij dowolny klawisz aby kontynuowac...";
    getch();
    system("cls");
    }

    return 0;
}

 

komentarz zamknięcia: Rozwiązany.

2 odpowiedzi

+2 głosów
odpowiedź 12 września 2016 przez BlackMoon Obywatel (1,730 p.)
wybrane 13 września 2016 przez 4sp3ll
 
Najlepsza

Ja zrobiłem to w ten sposób, że nie tworzyłem osobnej funkcji na menu, lecz wprowadziłem zmienną-strażnika.

Posłużyłem się tu zmienną typu bool, która zwraca tylko wartości true (zmienna==1) lub false (zmienna==0).

Żeby to w miarę obrazowo przedstawić:

1) Na początku wprowadzam zmienną: bool sprawdzam_poprawnosc; i nadaję jej domyślną wartość 0, czyli fałsz.

2) Następnie switch'a zamykam w pętli do {...} while(); a jako warunek while'a wstawiam mojego strażnika poprawności.

W ten sposób switch będzie się powtarzał, dopóki moja zmienna pilnująca (sprawdzam_poprawnosc) nie zmieni się na 1 (true), a w przypadku nieposłuszeństwa i wprowadzenia opcji której nie ma w menu, np. "7", "-12" lub "przypadkowy znak" program wypisywać będzie na ekranie twój komunikat z default ("Wybierz ponownie klawisz z listy...") i robił to nieustannie dopóki nie podasz jakiejś możliwej opcji (1,2,3,4 lub 5).

Teraz zastanów się w jakim przypadku i w których liniach kodu musisz zmienić zmienną sprawdzam_poprawnosc na 1 (true). 

Rozwiązanie nieco bardziej banalne, lecz jeśli jesteś początkujący i nie znasz się jeszcze na tworzeniu nowych funkcji w programie to właśnie w ten sposób możesz to obejść.

Daj znać jeśli masz jakieś pytania odnośnie do mojego rozwiązania. Mogę wrzucić kilka linijek przykładowego kodu wink

komentarz 13 września 2016 przez 4sp3ll Początkujący (410 p.)

Czy chodzi, mniej więcej, o coś takiego?:

        switch (wybor)
    {
        case '1': sprawdz_poprawnosc = 1;
            cout<<"Wynik dodawania: "<<x+y;
        break;

        case '2': sprawdz_poprawnosc = 1;
            cout<<"Wynik odejmowania: "<<x-y;
        break;

        case '3': sprawdz_poprawnosc = 1;
            cout<<"Wynik mnozenia: "<<x*y;
        break;

        case '4': sprawdz_poprawnosc = 1;
            if (y==0) cout<<"Nie dziel przez 0! ";
            else cout<<"Wynik dzielenia: "<<x/y;
        break;

        case '5':
            exit(0);
        break;

    } do;
        default: sprawdz_poprawnosc = 0;
            cout<<"Taka opcja nie jest dostepna"<<endl;
            cout<<"Wybierz ponownie klawisz z listy... "<<endl<<endl;

        break;
    }
    } while(sprawdz_poprawnosc==0);

Swoją drogą to co tutaj jest kończy się błędem, ale chce wiedzieć czy podążam we właściwym kierunku? Tak jak pisałem, jestem bardzo początkujący i analiza tych zagadnień jeszcze nie jest dla mnie czymś bardzo prostym.

komentarz 13 września 2016 przez BlackMoon Obywatel (1,730 p.)

Widzę, że poprawnie rozmieściłeś zmianę "sprawdz_poprawnosc". To znakomicie rozumiesz.

Błąd wyskakuje dlatego, że powinieneś zamknąć CAŁEGO switcha w pętli do {...} while(); i dodatkowo na początku samego do {...} ponowić prośbę o podanie znaku.

To co obecnie napisałeś jest nieskończoną pętlą, zresztą sam zobacz:

do
{
    default: sprawdz_poprawnosc = 0;
        cout<<"Taka opcja nie jest dostepna"<<endl;
        cout<<"Wybierz ponownie klawisz z listy... "<<endl<<endl; break;
} while(sprawdz_poprawnosc==0);

Na samym początku nadajesz wartość strażnikowi 0, lecz potem w obrębie do {...} while(); w ogóle nie zmienia się jego wartość (jest nieustannie równy 0), więc warunek w while (sprawdz_poprawnosc==0) jest zawsze spełniony co prowadzi do tego, że będzie non stop się powtarzał i wypisywał twój komunikat w nieskończoność.

Jak to naprawić?

1) Jak już wspomniałem, otwórz klamrę do {...} i na samym jej początku poproś użytkownika o podanie z klawiatury znaku komendą wybor=getch() (jak już to wcześniej zrobiłeś w swoim kodzie smiley), sprawi to, że po każdym przejściu pętli użytkownik będzie miał możliwość podać nowy znak.

2) Wprowadź switch'a zależnego od podanego z klawiatury znaku (to zrobiłeś poprawnie) i wypisz wszystkie przypadki case (pamiętaj o strażniku!).

3) Kiedy wypiszesz wszystkie przypadki i ustalisz zmianę strażnika zamknij do {...} i wprowadź warunek while(sprawdzam_poprawnosc==0).

Spełnij te wszystkie kroki, a twoja pętla będzie domagać się od użytkownika podania prawidłowego znaku i będzie na niego krzyczeć default'em jeśli tego nie zrobi angry.

komentarz 13 września 2016 przez 4sp3ll Początkujący (410 p.)

1) Jak już wspomniałem, otwórz klamrę do {...} i na samym jej początku poproś użytkownika o podanie z klawiatury znaku komendą wybor=getch()

Tak oczywiście zrobiłem w pierwszej kolejności, ale brakowało mi "wybor=getch()", dzięki!

Ok, działa:

#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <cstdlib>
#include <windows.h>

using namespace std;

float x,y;
char wybor;
bool sprawdz_poprawnosc=0;

int main()
{
    for(;;)
    {
    cout << "Podaj liczbe 1: ";
    cin>>x;
    cout<<endl;
    cout << "Podaj liczbe 2: ";
    cin>>y;
    cout<<endl;

    cout<<"Co chcesz zrobic z tymi liczbami?"<<endl;
    cout<<"=================================="<<endl;
    cout<<"1. Dodac"<<endl;
    cout<<"2. Odjac"<<endl;
    cout<<"3. Pomnozyc"<<endl;
    cout<<"4. Podzielic"<<endl;
    cout<<"5. Exit"<<endl;
    cout<<endl;
    cout<<"Wybierz klawisz z listy... "<<endl<<endl;
    wybor=getch();

    do
    {
        wybor=getch();

        switch (wybor)
    {
        case '1': sprawdz_poprawnosc = 1;
            cout<<"Wynik dodawania: "<<x+y;
        break;

        case '2': sprawdz_poprawnosc = 1;
            cout<<"Wynik odejmowania: "<<x-y;
        break;

        case '3': sprawdz_poprawnosc = 1;
            cout<<"Wynik mnozenia: "<<x*y;
        break;

        case '4': sprawdz_poprawnosc = 1;
            if (y==0) cout<<"Nie dziel przez 0! ";
            else cout<<"Wynik dzielenia: "<<x/y;
        break;

        case '5': sprawdz_poprawnosc = 1;
            exit(0);
        break;

        default: sprawdz_poprawnosc;
            cout<<"Taka opcja nie jest dostepna"<<endl;
            cout<<"Wybierz ponownie klawisz z listy... "<<endl<<endl;
        break;
    }
    } while(sprawdz_poprawnosc==0);

    cout<<endl;
    cout<<"Nacisnij dowolny klawisz aby kontynuowac...";
    getch();
    system("cls");
    }

    return 0;
}

Ale tutaj bardzo zastanawia mnie jedna rzecz, pętla do... while ma mieć taką konstrukcje:

 do
{
    //... tu powtarzany kod
} while( warunek_konczacy );

Zatem dlaczego, pętla powtarza się, a nie zrywa gdy wartość zmiennej "sprawdz_poprawnosc" osiąga 0?

Może powinien odpocząć, napić się herbaty i przemyśleć to jeszcze raz, ale obawiam się, że umknie mi to zagadnienie, dlatego pytam bez zwłoki.

komentarz 13 września 2016 przez BlackMoon Obywatel (1,730 p.)

Na samym wstępie: niepotrzebnie masz dwa razy wybór=getch(). Wystarczy tylko raz umieścić go w switch'u. Ten przed do{...} jest zbędny. 

Źle interpretujesz pętlę while() i pokrewną jej do {...} while().

"While" znaczy z angielskiego "dopóki" lub "gdy". A więc:

do
{
//... powtarzany kod
} while (straznik==0); 
//while mówi: będę powtarzał kod który mi dałeś, DOPÓKI zmienna straznik będzie równa 0

Gdy natomiast straznik przeskoczy na wartość 1 (ponieważ użytkownik podał poprawny znak i switch nada mu wartość 1) po przejściu całego kodu w klamrze while weźmie zmienną straznik i mówi: "Ojej! Wartość straznik nie jest równa 0! Skoro nie chcesz spełnić mojego warunku, to uciekaj od mojej pętli! angry " i następnie program opuszcza pętlę.

Czyli podsumowując, pętla while() wykonywana będzie cały czas, aż do momentu, gdy warunek w nim zawarty NIE BĘDZIE SPEŁNIONY. Gdy warunek jest false, czyli nie spełniony - pętla się urywa.

Słuszne uwagi na przyszłość z while() i do while():

1) Pamiętaj, że w warunku while możesz używać negacji. W tym przypadku byłoby to while(straznik!=1) co znaczy: rób to DOPÓKI straznik jest różny od 1. Jest to przydatne, bo nie raz uwalnia nasz umysł od zbytecznych logicznych łamigłówek cheeky

2) Widzę, że masz mało doświadczenia z while(), więc od razu zaznaczę różnicę pomiędzy do {...} while(), a samym while().

Program zawsze czyta linie kodu po kolei, dlatego używając do {...} while() program przynajmniej raz przejdzie przez kod umieszczony w klamrach do {...} i następnie porówna warunek w while().

Z drugiej strony, jeżeli użyjesz samego while() i potem klamry {...} to najpierw zostanie sprawdzony warunek, a dopiero potem wykonana instrukcja, więc istnieje możliwość, że pętla nie zaistnieje ani razu (jeżeli na samym początku warunek nie będzie spełniony)!

W twoim programie użyliśmy do {...} while(), ponieważ chcemy, aby użytkownik najpierw podał znak i dopiero kiedy to zrobi sprawdzimy go warunkiem while().

Jeżeli zrobilibyśmy sam while() to skąd program ma wiedzieć jaką wartość ma straznik, skoro użytkownik dopiero po sprawdzeniu while() dostanie możliwość wprowadzenia znaku.

Mam nadzieję, że rozwiałem wszelakie wątpliwości wink

komentarz 13 września 2016 przez 4sp3ll Początkujący (410 p.)

Rewelacja, dzięki za wszystkie komentarze! Najlepsza odpowiedź.

+2 głosów
odpowiedź 12 września 2016 przez Michał Kazula Pasjonat (19,540 p.)
Taka mała podpowiedź :-) Musisz podzielić ten kod na fragmenty (funkcje). Jedna funkcja ma odpowiadać za wyświetlenie i pobranie liczb do obliczeń. Druga funkcja to menu kalkulatora.

Mając funkcje menu_kalkulator() możesz ją wywołać w opcji default :-)
komentarz 12 września 2016 przez 4sp3ll Początkujący (410 p.)

Super podpowiedź! Działa, przy czym użyta jest tam funkcja goto której jeszcze nie było w kursie C++. 

Dodatkowo spotkałem się z licznymi negatywnymi komentarzami na temat funkcji goto.

Czy jest tutaj lepsza możliwość?

I czy jest dobry powód, który mogę zrozumieć na tym etapie nauki, dla którego nie powinienem korzystać z tej metody?

#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <cstdlib>
#include <windows.h>

using namespace std;

float x,y;
char wybor;

int main()
{
    for(;;)
    {
    cout << "Podaj liczbe 1: ";
    cin>>x;
    cout<<endl;
    cout << "Podaj liczbe 2: ";
    cin>>y;
    cout<<endl;

    menu:
    {
    cout<<"Co chcesz zrobic z tymi liczbami?"<<endl;
    cout<<"=================================="<<endl;
    cout<<"1. Dodac"<<endl;
    cout<<"2. Odjac"<<endl;
    cout<<"3. Pomnozyc"<<endl;
    cout<<"4. Podzielic"<<endl;
    cout<<"5. Exit"<<endl;
    cout<<endl;
    cout<<"Wybierz klawisz z listy... "<<endl<<endl;
    wybor=getch();
    }

        switch (wybor)
    {
        case '1':
            cout<<"Wynik dodawania: "<<x+y;
        break;

        case '2':
            cout<<"Wynik odejmowania: "<<x-y;
        break;

        case '3':
            cout<<"Wynik mnozenia: "<<x*y;
        break;

        case '4':
            if (y==0) cout<<"Nie dziel przez 0! ";
            else cout<<"Wynik dzielenia: "<<x/y;
        break;

        case '5':
            exit(0);
        break;

        default:
            cout<<"Taka opcja nie jest dostepna"<<endl;
            cout<<"Wybierz ponownie klawisz z listy... "<<endl<<endl;
            Sleep (1000);
            system("cls");
            goto menu;

        break;
    }

    cout<<endl;
    cout<<"Nacisnij dowolny klawisz aby kontynuowac...";
    getch();
    system("cls");
    }

    return 0;
}

 

komentarz 12 września 2016 przez Michał Kazula Pasjonat (19,540 p.)

Sam osobiście mam bardzo sceptyczne podejście do funkcji goto. 

Osobiście utworzyłbym dwie funkcje.

#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <cstdlib>
#include <windows.h>
 
using namespace std;
 
float x,y;
char wybor;
 
int main()
{
    for(;;)
    {
     getValue();
     menu(); 
    }
    return 0;
}

void getValue()
{
    cout << "Podaj liczbe 1: ";
    cin>>x;
    cout<<endl;
    cout << "Podaj liczbe 2: ";
    cin>>y;
    cout<<endl;
}

void menu()
{
 cout<<"Co chcesz zrobic z tymi liczbami?"<<endl;
    cout<<"=================================="<<endl;
    cout<<"1. Dodac"<<endl;
    cout<<"2. Odjac"<<endl;
    cout<<"3. Pomnozyc"<<endl;
    cout<<"4. Podzielic"<<endl;
    cout<<"5. Exit"<<endl;
    cout<<endl;
    cout<<"Wybierz klawisz z listy... "<<endl<<endl;
    wybor=getch();
    }
 
        switch (wybor)
    {
        case '1':
            cout<<"Wynik dodawania: "<<x+y;
        break; 
        case '2':
            cout<<"Wynik odejmowania: "<<x-y;
        break; 
        case '3':
            cout<<"Wynik mnozenia: "<<x*y;
        break; 
        case '4':
            if (y==0) cout<<"Nie dziel przez 0! ";
            else cout<<"Wynik dzielenia: "<<x/y;
        break; 
        case '5':
            exit(0);
        break; 
        default:
            cout<<"Taka opcja nie jest dostepna"<<endl;
            cout<<"Wybierz ponownie klawisz z listy... "<<endl<<endl;
            Sleep (1000);
            system("cls"); 
            menu();
        break;
    }
 
    cout<<endl;
    cout<<"Nacisnij dowolny klawisz aby kontynuowac...";
    getch();
    system("cls");
}

 

komentarz 12 września 2016 przez 4sp3ll Początkujący (410 p.)
edycja 12 września 2016 przez 4sp3ll

Wykonanie Twojego programu kończy się błędem.

LOG:

||=== Build: Debug in test (compiler: GNU GCC Compiler) ===| 
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp||In function 'int main()':| 
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|17|error: 'getValue' was not declared in this scope| 
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|18|error: 'menu' was not declared in this scope| 
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|47|error: expected unqualified-id before 'switch'| 
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|74|error: expected constructor, destructor, or type conversion before '<<' token| 
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|75|error: expected constructor, destructor, or type conversion before '<<' token| 
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|76|error: expected constructor, destructor, or type conversion before ';' token| 
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|77|error: expected constructor, destructor, or type conversion before '(' token| 
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|78|error: expected declaration before '}' token| 
||=== Build failed: 8 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

 

komentarz 12 września 2016 przez Michał Kazula Pasjonat (19,540 p.)

Przepraszam. Zapomniałem dopisać przed init'em deklaracji funkcji.

#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <cstdlib>
#include <windows.h>
  
using namespace std;
  
float x,y;
char wybor;

void getValue();
void menu();
  
int main()
{
    for(;;)
    {
     getValue();
     menu(); 
    }
    return 0;
}
 
void getValue()
{
    cout << "Podaj liczbe 1: ";
    cin>>x;
    cout<<endl;
    cout << "Podaj liczbe 2: ";
    cin>>y;
    cout<<endl;
}
 
void menu()
{
 cout<<"Co chcesz zrobic z tymi liczbami?"<<endl;
    cout<<"=================================="<<endl;
    cout<<"1. Dodac"<<endl;
    cout<<"2. Odjac"<<endl;
    cout<<"3. Pomnozyc"<<endl;
    cout<<"4. Podzielic"<<endl;
    cout<<"5. Exit"<<endl;
    cout<<endl;
    cout<<"Wybierz klawisz z listy... "<<endl<<endl;
    wybor=getch();
    }
  
        switch (wybor)
    {
        case '1':
            cout<<"Wynik dodawania: "<<x+y;
        break; 
        case '2':
            cout<<"Wynik odejmowania: "<<x-y;
        break; 
        case '3':
            cout<<"Wynik mnozenia: "<<x*y;
        break; 
        case '4':
            if (y==0) cout<<"Nie dziel przez 0! ";
            else cout<<"Wynik dzielenia: "<<x/y;
        break; 
        case '5':
            exit(0);
        break; 
        default:
            cout<<"Taka opcja nie jest dostepna"<<endl;
            cout<<"Wybierz ponownie klawisz z listy... "<<endl<<endl;
            Sleep (1000);
            system("cls"); 
            menu();
        break;
    }
  
    cout<<endl;
    cout<<"Nacisnij dowolny klawisz aby kontynuowac...";
    getch();
    system("cls");
}

 

komentarz 12 września 2016 przez 4sp3ll Początkujący (410 p.)

frown Dalej coś nie gra.

LOG:

||=== Build: Debug in test (compiler: GNU GCC Compiler) ===|
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|50|error: expected unqualified-id before 'switch'|
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|77|error: expected constructor, destructor, or type conversion before '<<' token|
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|78|error: expected constructor, destructor, or type conversion before '<<' token|
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|79|error: expected constructor, destructor, or type conversion before ';' token|
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|80|error: expected constructor, destructor, or type conversion before '(' token|
C:\Users\Tomasz\Desktop\nauka programowania\C++\Lekcja 6\test\main.cpp|81|error: expected declaration before '}' token|
||=== Build failed: 6 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

 

komentarz 12 września 2016 przez efiku Szeryf (75,160 p.)
edycja 12 września 2016 przez efiku

Czasem pomaga robienie funkcji z argumentami i przesyłaniem ich odpowiednio i pozbywanie się zmiennych globalnych, które są bardzo bardzo złe.

No i po Co Ci windows.h ;) 

Nie lepiej zrobić tak? 
 

Int main()
{
   for(;;)
  {
    // rysowanie menu (funkcja)
    //  pobierz krok i zwróć nr dzialania (funkcja)
    // wybierz opcje ( funkcja) : argument "opcja" 
   //  czyść ekran.

  }

  // wybierz krok : funkcja z switchem która na odpowiednią opcje odpala inne funkcje już 
 // dla danego działania, np  a * b
}

 

Podobne pytania

0 głosów
1 odpowiedź 506 wizyt
pytanie zadane 5 grudnia 2019 w C i C++ przez Apage Nowicjusz (140 p.)
0 głosów
0 odpowiedzi 254 wizyt
pytanie zadane 8 sierpnia 2018 w C i C++ przez sirwolfgur Nowicjusz (120 p.)
–1 głos
1 odpowiedź 176 wizyt
pytanie zadane 20 kwietnia 2018 w Offtop przez k3ybo4rd Obywatel (1,180 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 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!

...