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

Java/JavaFX/Odwołanie się do pola pustego Stringa

VPS Starter Arubacloud
0 głosów
134 wizyt
pytanie zadane 13 marca 2023 w Java przez elvis Nowicjusz (210 p.)

Witam,

Poniżej mój kod, który rozliczać ma paliwo w firmie. Okazuje się, że mam błąd 188 linia kodu przy odwołaniu się do pola pustego Stringa, proszę o pomoc. Całe źródła pod linkiem: https://mega.nz/file/Ss0EEQ4I#52jLLDy0Lz_K9YNDOEiGJ7IpflMO3pkqkHlQGCk2K48

 

package sample;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.Stage;
import javafx.scene.control.TextField;


import java.io.IOException;
import java.lang.invoke.VarHandle;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.*;
import java.util.concurrent.atomic.AtomicLong;

import static java.lang.Double.*;

public class Main extends Application {

    int lastid;
    Statement st;
    ResultSet rs;

    @FXML
    private TextField number_card_ID;
    @FXML
    private DatePicker date_card;
    @FXML
    private TextField number_card;
    @FXML
    private TextField counter_at_the_beginning;
    @FXML
    private TextField counter_at_the_end;
    @FXML
    private TextField number_of_km_driven;
    @FXML
    private TextField fuel_level_on_receipt_of_the_card;
    @FXML
    private TextField fuel_level_when_the_card_is_returned;
    @FXML
    private TextField number_of_operating_hours_of_the_unit;
    @FXML
    private TextField burning_oil_while_the_unit_is_running;
    @FXML
    private TextField amount_of_fuel_purchased;
    @FXML
    private TextField standard_fuel_consumption;
    @FXML
    private TextField fuel_actually_used_on_the_card;
    @FXML
    private TextField save_overheats;
    @FXML
    private TextField ilosc_zakupionego_paliwa;
    @FXML
    private TextField zuzyte_paliwo_faktycznie_z_karty;



    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("ROZLICZENIE PALIWA");
        primaryStage.setScene(new Scene(root, 1200, 768));
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }



    public void closeItemClicked(ActionEvent event) {

    }


    public void createdMenuClicked(ActionEvent event) {
        Parent root;
        try {
            root = FXMLLoader.load(getClass().getResource("sample.fxml"));
            Stage stage = new Stage();
            stage.setTitle("ZESTAWIENIE");
            stage.setScene(new Scene(root, 1024, 768));
            getLastid();
            stage.show();
            // Hide this current window (if this is what you want)
            //((Node)(event.getSource())).getScene().getWindow().hide();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }


    public void onenFilesMethod(ActionEvent event) {
    }

    public void saveTextToFile(ActionEvent event) {
    }

    public void getDateMethod(ActionEvent event) {
    }


    public static Connection connect() throws ClassNotFoundException {
        Class.forName("org.sqlite.JDBC");
        String url = "jdbc:sqlite:C:\\Program Files\\DB Browser for SQLite\\fuel.db";
        Connection conn = null;

        try {
            conn = DriverManager.getConnection(url);
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
        return conn;
    }

    //final AtomicLong identyfier = new AtomicLong(1);

    public void insert() throws ClassNotFoundException {
        String sql = ("INSERT INTO tally ('number_card_ID', 'date_card', 'counter_at_the_beginning', 'counter_at_the_end', " +
                "'number_of_km_driven', 'fuel_level_on_receipt_of_the_card', 'fuel_level_when_the_card_is_returned', " +
                "'number_of_operating_hours_of_the_unit', 'burning_oil_while_the_unit_is_running', " +
                "'amount_of_fuel_purchased', 'standard_fuel_consumption', 'fuel_actually_used_on_the_card', 'save_overheats') " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        try (Connection conn = this.connect();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, number_card_ID.getText());
            pstmt.setString(2, ((TextField) date_card.getEditor()).getText());
            pstmt.setString(3, counter_at_the_beginning.getText());
            pstmt.setString(4, counter_at_the_end.getText());
            pstmt.setString(5, number_of_km_driven.getText());
            pstmt.setString(6, fuel_level_on_receipt_of_the_card.getText());
            pstmt.setString(7, fuel_level_when_the_card_is_returned.getText());
            pstmt.setString(8, number_of_operating_hours_of_the_unit.getText());
            pstmt.setString(9, burning_oil_while_the_unit_is_running.getText());
            pstmt.setString(10, amount_of_fuel_purchased.getText());
            pstmt.setString(11, standard_fuel_consumption.getText());
            pstmt.setString(12, fuel_actually_used_on_the_card.getText());
            pstmt.setString(13, save_overheats.getText());

            //date_card = new DatePicker();
            //date_card.setPromptText("Data");
            pstmt.executeUpdate();
            conn.close();
        } catch (SQLException | ClassNotFoundException e) {
            System.out.println(e.getMessage());
        }
    }

    public void getLastid() {

        String sql = "select max(number_card_ID) from tally";

        try (Connection conn = this.connect();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            if (rs.next()) {
                lastid = rs.getInt(1);
                lastid++;
                number_card_ID.setText(Integer.toString(lastid));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void clickButton() throws ClassNotFoundException, SQLException {
            int number1 = Integer.valueOf(counter_at_the_beginning.getText());
            int number2 = Integer.valueOf(number_of_km_driven.getText());
            int sum1 = number1 + number2;
            counter_at_the_end.setText(String.format(String.valueOf(sum1)));

            double number3 = valueOf(fuel_level_on_receipt_of_the_card.getText());
            //System.out.println(number3);
            double number4 = valueOf(amount_of_fuel_purchased.getText());
            double number5 = valueOf(fuel_actually_used_on_the_card.getText());
            double sum2 = number3 + number4 - number5;
            BigDecimal bigDecimal = new BigDecimal(sum2).setScale(2, RoundingMode.HALF_UP);
            double newBigDecimal = bigDecimal.doubleValue();
            fuel_level_when_the_card_is_returned.setText(String.valueOf(newBigDecimal));

            double number6 = valueOf(burning_oil_while_the_unit_is_running.getText());
            double sum3 = ((number2 * 28) / 100) + number6;
            BigDecimal bigDecimal1 = new BigDecimal(sum3).setScale(2, RoundingMode.HALF_UP);
            double newBigDecimal1 = bigDecimal1.doubleValue();
            standard_fuel_consumption.setText(String.valueOf(newBigDecimal1));

            double number7 = valueOf(number_of_operating_hours_of_the_unit.getText());
            double number8 = valueOf(burning_oil_while_the_unit_is_running.getText());
            double sum4 = number7 * number8;
            BigDecimal bigDecimal2 = new BigDecimal(sum4).setScale(2, RoundingMode.HALF_UP);
            double newBigDecimal2 = bigDecimal2.doubleValue();
            burning_oil_while_the_unit_is_running.setText(String.valueOf(newBigDecimal2));

            // to może być błędne (przedostatnia komórka Excela)
            double number9 = valueOf(standard_fuel_consumption.getText());
            System.out.println(number9);
            double number10 = valueOf(fuel_actually_used_on_the_card.getText());
            System.out.println(number10);
            number10 = number9;
            System.out.println(number10);
            fuel_actually_used_on_the_card.setText(String.valueOf(number10));

            //oszczędności/przepały
            // fuel_actually_used_on_the_card - standard_fuel_consumption
            double number11 = valueOf(fuel_actually_used_on_the_card.getText());
            double number12 = valueOf(standard_fuel_consumption.getText());
            double difference = number11 - number12;
            BigDecimal bigDecimal3 = new BigDecimal(difference).setScale(2, RoundingMode.HALF_UP);
            double newBigDecimal3 = bigDecimal3.doubleValue();
            save_overheats.setText(String.valueOf(newBigDecimal3));




    }
}

 

komentarz 13 marca 2023 przez Wiciorny Ekspert (269,120 p.)

Jedynie co może być problemem, to brak uzupełnionego pola 
 

@FXML
    private TextField fuel_actually_used_on_the_card;

chociaż wolałbym zobaczyć "stacktrace błędu" 

2 odpowiedzi

0 głosów
odpowiedź 13 marca 2023 przez VBService Ekspert (251,270 p.)
edycja 13 marca 2023 przez VBService

przy odwołaniu się do pola pustego

Spróbuj np. tego:

  1. is there a Java equivalent to null coalescing operator (??) [ 2 ]
  2. Null Coalescing in Java 8

 

 

BTW, aaałć, ścieżka bezwzględna do pliku bazy danych

String url = "jdbc:sqlite:C:\\Program Files\\DB Browser for SQLite\\fuel.db";

 

komentarz 13 marca 2023 przez Wiciorny Ekspert (269,120 p.)
DriverManager.getConnection(url)

Nie oczekuje ścieżki bezwzględnej, tylko ścieżki do bazy a to co innego 
Jeśli kożysta z jdk >14 to bez znaczenia jest  nawet fakt "\\"

getConnection(String url)

Attempts to establish a connection to the given database URL.

Akurat sqllite ma poprawną konfiguracje e.g jdbc:sqlite:C:/your_path/your.db

komentarz 13 marca 2023 przez VBService Ekspert (251,270 p.)

Zgaduję, że aplikacja jest uruchamiana z innej lokalizacji, a po przeniesieniu na inny komputer, co plik bazy danych, będzie się znajdował w:

C:\\Program Files\\DB Browser for SQLite\\fuel.db

no bo jest na sztywno przypisana lokalizacja pliku w kodzie

String url = "jdbc:sqlite:C:\\Program Files\\DB Browser for SQLite\\fuel.db";

IMHO słabo to wygląda, dobrze jest jak plik bazy danych znajduje się w folderze gdzie znajduje się "fizycznie" aplikacja lub w folderze profilu użytkownika, oczywiście nie jest to przymus, ale ułatwia "przenoszenie" aplikacji na inny komputer - Ja np. nie lubię zaśmiecać sobie dysku C: - systemowego (windows) a tym bardziej Program Files, dlatego na ten przykład mam 97% aplikacji w wersji portable, druga korzyść po np. reinstalacji, aplikacje są dostępne od razu.

komentarz 13 marca 2023 przez Wiciorny Ekspert (269,120 p.)

zaglądasz czasmi do metod, których używasz jak programujesz?
 

/*
 * Load the initial JDBC drivers by checking the System property
 * jdbc.drivers and then use the {@code ServiceLoader} mechanism
 */
private static void ensureDriversInitialized() {
...

popatrz sobie co się dzieje, w sytuacji kiedy driver nie znajdzie lokalizacji na baze, ale ktoś "UŻTYKOWNIK" który skorzysta z api - np. zbudowanej w exe, ma na komputerze :) sterownik. Inna sprawa, że to nie jest temat pytania i nie jest to problem tego autora, dodatkowo nie wiesz co chce zrobić z aplikacja, skoro i tak nie ma w properites tego zapisanego to i tak jest na te chwile to bez znaczenia, portable żeby apke zrobić w ten sposób musiałby dołączyć wszystkie biblioteki dla FX :) dodatkowo całą baze z plikami w output jar i następnie np exe, lub war w zależności od tego jak ktoś ma to uruchamiać. 
A bez licencji MIT nie może tego zrobić jeśli chodzi o deploy globalny z plikami na braku licencji. 

komentarz 13 marca 2023 przez Wiciorny Ekspert (269,120 p.)

jeszcze jeśli zajdzie problem, że nie bedzie driverów to ostatecznie JVM spróbuje raz preszukać to z pomocą 

 @CallerSensitive

za pomocą refleksji. 

To co piszesz miałoby sens i jest prawdą gdyby autor o to zapytał i to było problemem. 

komentarz 13 marca 2023 przez Wiciorny Ekspert (269,120 p.)
a jak chcemy być tak bardzo PORTABLE, to w takich aplikacjach takie parametry ustawiane są na classpath VM javy, jako argumenty. I tylko i wyłącznie tak to jest konfigurowane, nigdy z poziomu kodu, bo równie dobrze, dekompilacja  mogłaby spowodować widoczność do danych wrażliwych szczególnie do stringów, które są przechowywane bardzo długo zanim GC je usunie, gdyż jeszcze taki string siedzi jako osobna referencja do String pool
komentarz 13 marca 2023 przez VBService Ekspert (251,270 p.)

To co piszesz miałoby sens i jest prawdą gdyby autor o to zapytał i to było problemem. 

dlatego zapisałem to po BTW, czyli coś na co może zwróci uwagę, ale nie musi, Jego wybór (OP-a)

i napisałem w komentarzu

... oczywiście nie jest to przymus

0 głosów
odpowiedź 13 marca 2023 przez elvis Nowicjusz (210 p.)

Kod błędu to:

"C:\Program Files\openjdk-11.0.1_windows-x64_bin\jdk-11.0.1\bin\java.exe" --module-path "C:\Program Files\openjfx-11.0.2_windows-x64_bin-sdk\javafx-sdk-11.0.2\lib" --add-modules=javafx.controls,javafx.fxml "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.5\lib\idea_rt.jar=51262:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.5\bin" -Dfile.encoding=UTF-8 -classpath C:\testOkienek\out\production\testOkienek;C:\Users\Rafał_2\.m2\repository\org\openjfx\javafx-fxml\11\javafx-fxml-11.jar;C:\Users\Rafał_2\.m2\repository\org\openjfx\javafx-fxml\11\javafx-fxml-11-win.jar;C:\Users\Rafał_2\.m2\repository\org\openjfx\javafx-controls\11\javafx-controls-11.jar;C:\Users\Rafał_2\.m2\repository\org\openjfx\javafx-controls\11\javafx-controls-11-win.jar;C:\Users\Rafał_2\.m2\repository\org\openjfx\javafx-graphics\11\javafx-graphics-11.jar;C:\Users\Rafał_2\.m2\repository\org\openjfx\javafx-graphics\11\javafx-graphics-11-win.jar;C:\Users\Rafał_2\.m2\repository\org\openjfx\javafx-base\11\javafx-base-11.jar;C:\Users\Rafał_2\.m2\repository\org\openjfx\javafx-base\11\javafx-base-11-win.jar;C:\testOkienek;C:\testOkienek\lib\sqlite-jdbc-3.7.2.jar sample.Main
mar 13, 2023 9:51:16 PM javafx.fxml.FXMLLoader$ValueElement processValue
WARNING: Loading FXML document with JavaFX API of version 16 by JavaFX runtime of version 11.0.2
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
	at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787)
	at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
	at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
	at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
	at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
	at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
	at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
	at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
	at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
	at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
	at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
	at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
	at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8879)
	at javafx.controls/javafx.scene.control.Button.fire(Button.java:200)
	at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
	at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
	at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
	at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
	at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
	at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
	at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
	at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
	at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
	at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
	at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
	at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
	at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
	at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3851)
	at javafx.graphics/javafx.scene.Scene$MouseHandler.access$1200(Scene.java:3579)
	at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1849)
	at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2588)
	at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
	at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
	at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:390)
	at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
	at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
	at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
	at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
	at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
	at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
	at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
	at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1784)
	... 47 more
Caused by: java.lang.NumberFormatException: empty String
	at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
	at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.base/java.lang.Double.parseDouble(Double.java:543)
	at java.base/java.lang.Double.valueOf(Double.java:506)
	at sample.Main.clickButton(Main.java:188)
	... 58 more

Problem właśnie jest z polem:

fuel_actually_used_on_the_card

W linii 188 odwołuje się do niego, a tak naprawdę informacja o tym polu jest w linii dopiero 214.

Podobne pytania

0 głosów
0 odpowiedzi 362 wizyt
pytanie zadane 28 sierpnia 2020 w Java przez Kacper Sas Dyskutant (8,460 p.)
0 głosów
1 odpowiedź 1,104 wizyt
0 głosów
1 odpowiedź 169 wizyt
pytanie zadane 29 grudnia 2018 w Java przez ILikeJava Obywatel (1,230 p.)

92,455 zapytań

141,263 odpowiedzi

319,099 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!

...