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

Interfejs menu w C++

0 głosów
771 wizyt
pytanie zadane 7 marca 2025 w Nasze projekty przez whiteman808 Mądrala (5,540 p.)
edycja 7 marca 2025 przez whiteman808

Hej, napisałem interfejs menu w C++. Co sądzicie o moim programie, co mogę w nim poprawić? Czy jest coś do poprawy w kodzie źródłowym?

~/programy_cpp/linked_list ❯ cat main.cpp                                                                                                             17:30:52
// the purpose of the below code is to test menu class

#include <ios>
#include <iostream>
#include <limits>
#include <string>
#include <utility>
#include "menu.h"

/*
 * these functions are defined only to test menu.h library
 * i plan to merge these functions to the CalculatorApp class
 * in the future
 *
 * i wrote below code in a hurry
 */

// helper functions; will be moved into utils.h/utils.cpp in the future
inline void clear_console_input() {
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

double read_double(const std::string& prompt = "Enter the number: ") {
    double number;
    bool success{false};
    do {
        std::cout << prompt;
        if (std::cin >> number) {
            success = true;
        } else {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "Error: not a number." << std::endl;
        }
    } while (!success);
    return number;
}

std::pair<double, double> read_operands() {
    double first{read_double("Enter the first operand: ")};
    double second{read_double("Enter the second operand: ")};
    clear_console_input();
    return std::make_pair(first, second);
}

std::pair<double, double> read_operands_div() {
    double first{read_double("Enter the first operand: ")};
    double second;
    while ((second = read_double("Enter the second operand: ")) == 0) {
        std::cout << "Error: number is equal to zero." << std::endl;
    }
    clear_console_input();
    return std::make_pair(first, second);
}

// calculator interface
void add() {
    auto numbers = read_operands();
    std::cout << "Result of " << numbers.first << " + " << numbers.second
              << " is " << numbers.first + numbers.second << std::endl;
}

void subtract() {
    auto numbers = read_operands();
    std::cout << "Result of " << numbers.first << " - " << numbers.second
              << " is " << numbers.first - numbers.second << std::endl;
}

void multiply() {
    auto numbers = read_operands();
    std::cout << "Result of " << numbers.first << " * " << numbers.second
              << " is " << numbers.first * numbers.second << std::endl;
}

void divide() {
    auto numbers = read_operands_div();
    std::cout << "Result of " << numbers.first << " / " << numbers.second
              << " is " << numbers.first / numbers.second << std::endl;
}

int main() {
    menu app{"Calculator"};
    app.add_item("Add", add);
    app.add_item("Subtract", subtract);
    app.add_item("Multiply", multiply);
    app.add_item("Divide", divide);
    menu menu2{"test"};
    app.add_submenu(menu2);
    app.loop();
    std::cout << "Good bye!\n";
    return 0;
}
~/programy_cpp/linked_list ❯ cat menu.h                                                                                                               17:30:55
#ifndef MENU_H
#define MENU_H

#include <functional>
#include <iostream>
#include <string>
#include <vector>

struct menu_item {
    explicit menu_item(const std::string& title_val) : title{title_val}, action{noop} {}
    menu_item(const std::string& title_val, std::function<void()> action_val)
        : title{title_val}, action{action_val} {}
    menu_item(const menu_item& item) : title{item.title}, action{item.action} {}

    friend std::ostream& operator<<(std::ostream& lhs, const menu_item& rhs);

    static void noop() { std::cout << "No action defined!\n"; }

    std::string title{};
    std::function<void()> action{};
};

class menu {
public:
    explicit menu(const std::string& title_val);
    menu(const std::string& title_val, const std::vector<menu_item>& items_val);
    menu(const std::string& title_val, const std::string& description_val);
    menu(const std::string& title_val, const std::string& description_val,
         const std::vector<menu_item>& items_val);

    void add_item(const menu_item& item);
    void add_item(const std::string& title_val, std::function<void()> action);
    void add_item_at(int index, const menu_item& item);
    void add_item_at(int index, const std::string& title_val,
                     std::function<void()> action);
    void remove_item(int index);

    void add_submenu(const menu& menu_val);
    void add_submenu(const std::string& title_val, const menu& menu_val);
    void add_submenu_at(int index, const menu& menu_val);
    void add_submenu_at(int index, const std::string& title_val,
                        const menu& menu_val);

    void set_title(const std::string& title_val);
    void set_description(const std::string& description_val);

    void loop() const;

private:
    // helper functions
    void print_choices() const;
    char read_choice() const;
    void check_index(std::size_t index) const;

    // wrapper function for menu::loop
    std::function<void()> invoke_menu_loop(const menu& menu_val);

    static int nesting_level;
    std::string title{};
    std::string description{};
    std::vector<menu_item> items{};
};

#endif // MENU_H
~/programy_cpp/linked_list ❯ cat menu.cpp                                                                                                             17:30:58
#include "menu.h"
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

static constexpr char quit_choice = 'q';

// helper functions
static void print_title(const std::string& title) {
    std::size_t title_len = title.size();
    std::size_t width = title_len + 4;
    for (std::size_t i = 0; i < width; ++i) {
        std::cout << "*";
    }
    std::cout << "\n* " << title << " *\n";
    for (std::size_t i = 0; i < width; ++i) {
        std::cout << "*";
    }
    std::cout << std::endl;
}

// menu_item struct i/o operators
std::ostream& operator<<(std::ostream& lhs, const menu_item& rhs) {
    return lhs << rhs.title;
}

// menu class constructors
menu::menu(const std::string& title_val) : title{title_val} {}

menu::menu(const std::string& title_val,
           const std::vector<menu_item>& items_val)
    : title{title_val}, items{items_val} {}

menu::menu(const std::string& title_val, const std::string& description_val)
    : title{title_val}, description{description_val} {}

menu::menu(const std::string& title_val, const std::string& description_val,
           const std::vector<menu_item>& items_val)
    : title{title_val}, description{description_val}, items{items_val} {}

// menu class static variables
int menu::nesting_level{0};

// menu class public interface
void menu::add_item(const menu_item& item) { items.push_back(item); }

void menu::add_item(const std::string& title_val, std::function<void()> action_val) {
    items.push_back(menu_item{title_val, action_val});
}

void menu::add_item_at(int index, const menu_item& item) {
    check_index(index);
    items.insert(items.begin() + index, item);
}

void menu::add_item_at(int index, const std::string& title_val,
                       std::function<void()> action) {
    check_index(index);
    items.insert(items.begin() + index, menu_item{title_val, action});
}

void menu::remove_item(int index) {
    check_index(index);
    items.erase(items.begin() + index);
}

void menu::add_submenu(const menu& menu_val) {
    items.push_back(menu_item{menu_val.title, invoke_menu_loop(menu_val)});
}

void menu::add_submenu(const std::string& title_val, const menu& menu_val) {
    items.push_back(menu_item{title_val, invoke_menu_loop(menu_val)});
}

void menu::add_submenu_at(int index, const menu& menu_val) {
    check_index(index);
    items.insert(items.begin() + index,
                 menu_item{menu_val.title, invoke_menu_loop(menu_val)});
}

void menu::add_submenu_at(int index, const std::string& title_val,
                          const menu& menu_val) {
    check_index(index);
    items.insert(items.begin() + index,
                 menu_item{title_val, invoke_menu_loop(menu_val)});
}

void menu::set_title(const std::string& title_val) { title = title_val; }

void menu::set_description(const std::string& description_val) {
    description = description_val;
}

void menu::loop() const {
    bool active = true;
    ++nesting_level;
    while (active) {
        print_title(title);
        if (!description.empty()) {
            std::cout << std::endl;
            std::cout << description;
            std::cout << std::endl;
        }
        char choice = read_choice();
        if (choice == quit_choice) {
            --nesting_level;
            active = false;
        } else {
            std::cout << '\n';
            // call function bound to menu item
            items[choice - '0'].action();
            // wait until user press the enter key
            std::cout << "\nPress enter to continue...\n";
            std::cin.get();
        }
    }
}

// menu class private functions
void menu::print_choices() const {
    for (std::size_t i = 0; i < items.size(); ++i) {
        std::cout << i << ") " << items[i] << std::endl;
    }
    std::cout << "q) ";
    if (nesting_level > 1)
        std::cout << "Back";
    else
        std::cout << "Quit";
    std::cout << std::endl;
}

char menu::read_choice() const {
    std::string user_input;
    char choice;
    bool valid{false};

    std::cout << "What do you want to do?\n";
    do {
        print_choices();
        std::cout << "Your choice: ";
        std::getline(std::cin, user_input);
        if (user_input.length() > 1 || user_input.empty()) {
            std::cout << "Please enter the valid choice.\n";
            continue;
        }
        choice = tolower(user_input.at(0));
        if ((choice - '0') < 0 ||
            (static_cast<std::size_t>(choice - '0') >= items.size() &&
             (choice != quit_choice))) {
            std::cout << "Invalid choice!\n";
        } else {
            valid = true;
        }
    } while (!valid);
    return choice;
}

void menu::check_index(std::size_t index) const {
    const std::size_t max_allowed_idx = items.size() - 2;
    if (index > max_allowed_idx) {
        std::ostringstream oss;
        oss << "index value must be between " << index << " and "
            << max_allowed_idx;
        throw std::out_of_range{oss.str()};
    }
}

// wrapper function for menu::loop
std::function<void()> menu::invoke_menu_loop(const menu& the_menu) {
    return [&the_menu]() { the_menu.loop(); };
}

1 odpowiedź

–1 głos
odpowiedź 11 marca 2025 przez Yolo Nowicjusz (160 p.)
edycja 11 marca 2025 przez Yolo

Twój kod jest całkiem czytelny i modularny – dobra robota! Zauważyłem jednak kilka obszarów, w których można by wprowadzić ulepszenia:

 

1. Walidacja indeksu w funkcji check_index

Problem: Funkcja check_index oblicza maksymalny dozwolony indeks jako items.size() - 2. To może być problematyczne, gdy lista jest mała – na przykład przy dodawaniu lub usuwaniu elementów w menu. W praktyce poprawnym zakresem dla operacji na wektorze jest [0, items.size() – 1] (dla usuwania) lub [0, items.size()] (dla wstawiania na końcu).

Sugestia: Zastanów się nad wprowadzeniem osobnych walidacji dla operacji wstawiania i usuwania. Możesz np. dla usuwania sprawdzać, czy index < items.size(), a dla wstawiania czy index <= items.size(). Dzięki temu unikniesz sytuacji, gdy poprawny indeks zostanie błędnie odrzucony lub doprowadzi do nieoczekiwanych wyjątków.

2. Obsługa wyboru użytkownika w read_choice

Problem: Aktualnie wybór użytkownika jest odczytywany jako pojedynczy znak, a następnie odejmujesz wartość '0', aby uzyskać indeks. Jeśli użytkownik wprowadzi znak niebędący cyfrą (np. literę), konwersja może dawać nieoczekiwane rezultaty.

Sugestia: Rozważ dodanie jawnej weryfikacji, czy wprowadzony znak jest cyfrą (np. przy pomocy std::isdigit) przed konwersją. Alternatywnie możesz wykorzystać funkcję, która próbuje przekonwertować cały ciąg znaków na liczbę (np. std::stoi), co może zwiększyć czytelność i bezpieczeństwo kodu.

3. Komunikaty o błędach i obsługa wyjątków

Problem: Wywołanie check_index w funkcjach takich jak add_item_at lub remove_item może rzucić wyjątek. W obecnej wersji programu nie ma mechanizmu, który łapałby te wyjątki ani nie informował użytkownika o błędzie w czytelny sposób.

Sugestia: Rozważ dodanie obsługi wyjątków w miejscu, gdzie korzystasz z tych funkcji, aby w razie wystąpienia błędu program mógł bezpiecznie poinformować użytkownika lub zaproponować ponowienie operacji.

4. Struktura kodu i organizacja

Dobre praktyki: Podział funkcjonalności (np. pomocnicze funkcje do wczytywania liczb) do osobnego modułu, jak planowałeś, to dobry krok. Dzięki temu kod główny będzie bardziej przejrzysty.

Sugestia: Możesz rozważyć także dodatkowe komentarze lub dokumentację (np. w formie Doxygen), aby łatwiej było utrzymać i rozwijać projekt w przyszłości.

5. Drobne usprawnienia

Nazwa menu: W main.cpp utworzyłeś submenu (menu menu2{"test"}), które nie zawiera żadnych elementów. Może warto dodać do niego jakieś przykładowe pozycje lub rozszerzyć przykład, aby pokazać pełnię funkcjonalności.

Czyszczenie wejścia: Funkcja clear_console_input jest przydatna – upewnij się, że zawsze jest wywoływana w miejscach, gdzie może pozostać zalegający znak końca linii.

Podsumowując, Twój interfejs menu prezentuje się bardzo dobrze, a zastosowanie lambd do obsługi submenu jest ciekawym rozwiązaniem. Kluczowe obszary do poprawy to walidacja indeksów oraz bezpieczna konwersja wyboru użytkownika. Wprowadzenie powyższych usprawnień zwiększy odporność Twojego programu na błędy i poprawi jego czytelność.                                                              

Poniżej przedstawiam zmodyfikowaną wersję fragmentów kodu – dodałem dwie osobne funkcje do walidacji indeksu (dla operacji odczytu/usuwania oraz dla wstawiania) oraz zmodyfikowałem funkcję read_choice(), aby przed konwersją sprawdzała, czy użytkownik wprowadził cyfrę przy użyciu std::isdigit.

Zmiany w walidacji indeksów

W oryginalnej wersji funkcja check_index obliczała maksymalny dozwolony indeks jako items.size() - 2, co może powodować problemy. Teraz wprowadzamy dwie oddzielne funkcje:

// W menu.cpp dodajemy dwie nowe funkcje walidujące indeksy:

// Dla operacji odczytu/usuwania – poprawny zakres: [0, items.size()-1]
void menu::check_index_access(std::size_t index) const {
    if (index >= items.size()) {
        std::ostringstream oss;
        oss << "Index " << index << " is out of range. Valid indices: [0, " 
            << (items.size() > 0 ? items.size() - 1 : 0) << "].";
        throw std::out_of_range(oss.str());
    }
}

// Dla operacji wstawiania – poprawny zakres: [0, items.size()]
void menu::check_index_insertion(std::size_t index) const {
    if (index > items.size()) {
        std::ostringstream oss;
        oss << "Index " << index << " is out of range for insertion. Valid indices: [0, " 
            << items.size() << "].";
        throw std::out_of_range(oss.str());
    }
}

Dla operacji dostępu/usuwania: Poprawny indeks musi należeć do przedziału [0, items.size()-1].

Dla operacji wstawiania: Dozwolone są indeksy w przedziale [0, items.size()].

Następnie w funkcjach takich jak add_item_at, add_submenu_at oraz remove_item wywołujemy odpowiednią funkcję walidacyjną:

void menu::add_item_at(int index, const menu_item& item) {
    check_index_insertion(index);
    items.insert(items.begin() + index, item);
}

void menu::add_item_at(int index, const std::string& title_val, std::function<void()> action) {
    check_index_insertion(index);
    items.insert(items.begin() + index, menu_item{title_val, action});
}

void menu::remove_item(int index) {
    check_index_access(index);
    items.erase(items.begin() + index);
}

void menu::add_submenu_at(int index, const menu& menu_val) {
    check_index_insertion(index);
    items.insert(items.begin() + index, menu_item{menu_val.title, invoke_menu_loop(menu_val)});
}

void menu::add_submenu_at(int index, const std::string& title_val, const menu& menu_val) {
    check_index_insertion(index);
    items.insert(items.begin() + index, menu_item{title_val, invoke_menu_loop(menu_val)});
}

Bezpieczna konwersja wyboru użytkownika

W funkcji read_choice() dodałem dodatkową walidację – przed konwersją sprawdzamy, czy użytkownik wprowadził pojedynczy znak oraz czy jest to cyfra (lub znak q na wyjście). Dzięki temu unikamy nieoczekiwanych konwersji.

char menu::read_choice() const {
    std::string user_input;
    char choice;
    bool valid{false};

    std::cout << "What do you want to do?\n";
    do {
        print_choices();
        std::cout << "Your choice: ";
        std::getline(std::cin, user_input);
        if (user_input.length() != 1) {
            std::cout << "Invalid input. Please enter exactly one character.\n";
            continue;
        }
        choice = std::tolower(user_input[0]);
        if (choice == quit_choice) {
            valid = true;
        } else if (std::isdigit(choice)) {
            int idx = choice - '0';
            if (static_cast<std::size_t>(idx) < items.size()) {
                valid = true;
            } else {
                std::cout << "Invalid choice! Please select a valid index.\n";
            }
        } else {
            std::cout << "Invalid input! Please enter a digit or '" << quit_choice << "'.\n";
        }
    } while (!valid);
    return choice;
}
3
komentarz 11 marca 2025 przez Arkadiusz Waluk Ekspert (291,410 p.)
Prosimy nie wstawiać na forum wypowiedzi wygenerowanych przez AI. Zakładamy, że jeśli ktoś pyta na forum, to jednak oczekuje realnej pomocy innych ludzi, a jeśli będzie potrzebował automatu, to spróbuje z nim porozmawiać sam. W taki sposób to całe forum mogłoby się opierać na tym, że wrzucamy pytania, Czat GPT generuje odpowiedzi i nikt tu nie jest potrzebny, a to chyba nie o to chodzi :) Wolimy mniejszą liczbę czy krótsze, ale bardziej jakościowe i pomocne odpowiedzi napisane samodzielnie.
komentarz 12 marca 2025 przez Yolo Nowicjusz (160 p.)

Szanowny Administratorze,

Dziękuję za reakcję, jednak Twoja odpowiedź jest niemerytoryczna i nie odnosi się do samego zagadnienia, które było przedmiotem dyskusji. Jeśli zasady forum rzeczywiście zabraniają publikowania odpowiedzi wygenerowanych przez AI, to proszę o wskazanie konkretnego punktu regulaminu, na którym opierasz swoją decyzję. Jeśli takiego zapisu brak, to należy rozważyć jego dodanie zamiast arbitralnego podejmowania decyzji według własnego uznania.

Ponadto Twoje argumenty są wewnętrznie sprzeczne – sam korzystasz z usług AI, ale chcesz tego zabronić innym. To podejście nie tylko ogranicza potencjał pomocy, ale również wprowadza subiektywne zasady, które nie służą nikomu poza osobistymi przekonaniami.

Dyskusja na forum powinna skupiać się na wartości merytorycznej odpowiedzi, niezależnie od tego, kto lub co ją wygenerowało. Liczy się skuteczność i trafność rozwiązania, a nie źródło jego pochodzenia. Każdy może zweryfikować jakość podanej informacji i ocenić jej użyteczność.

Wolimy dobrze sformułowane i trafne odpowiedzi, zamiast subiektywnie ocenianych „krótszych i bardziej jakościowych”, których jakość tak naprawdę nie jest obiektywnie weryfikowana. Jeśli wartość merytoryczna mojej odpowiedzi była pomocna dla pytającego, to nie widzę powodu, by ją usuwać – tym bardziej że forum ma służyć rozwiązywaniu problemów, a nie spełnianiu osobistych wizji sposobu prowadzenia dyskusji.

Proszę o przemyślenie tego podejścia, bo w obecnym kształcie jest to po prostu niekonsekwentne. Jeśli regulamin tego zabrania, proszę o jego aktualizację i jasne określenie zasad – jeśli nie, to szkoda czasu na bezcelową dyskusję.

Pozdrawiam.

2
komentarz 12 marca 2025 przez Arkadiusz Waluk Ekspert (291,410 p.)
Mój komentarz nie odnosi się do merytoryki pytania, bo musiałem zwrócić uwagę, więc siłą rzeczy ciężko w zwracaniu komuś uwagi (niezależnie z jakiego powodu) udzielać jednocześnie merytorycznej odpowiedzi na pytanie.

Podane argumenty nie są sprzeczne, nie wiem skąd taki wniosek. Nie wiem też skąd masz informację, że sam używam AI, poprosiłbym o źródło. A nawet jeśli bym używał, to liczy się też zakres i cel użycia. Nie każde narzędzie i przedmiot w naszym życiu jest domyślnie zły, powiedziałbym wręcz, że domyślnie większość jest dobra i pomocna, kwestia tego jak się go użyje.

W AI, także w kontekście użycia w programowaniu, nie widzę nic złego, o ile ktoś używa go jako wsparcia, doradcy i pomocy, a nie generatora, który będzie pisał całe rozwiązania i odpowiedzi, a ktoś bez przemyślenia będzie je kopiował dalej. Podtrzymuję, że w takiej formie jaką chcesz tu wprowadzić, na forum nie byliby potrzebni użytkownicy i miejsce na odpowiedzi. Przecież można podpiąć Chat GPT po API, to nie jest żaden problem, wtedy ktoś by zadawał pytanie na forum, a Chat GPT od razu w sekundy generował odpowiedź i koniec dyskusji. Tylko po co wtedy forum i ludzie tutaj? Każdy sam sobie może wejść na Chat GPT lub wziąć inny darmowy model i go zapytać, więc opisanej wizji bez ludzi byśmy jednak nie chcieli.

W regulaminie obecnie nie ma wprost punktu zakazującego używanie AI, ale ze względu na powtarzające się już od jakiegoś czasu problemy tego typu przy najbliższej jego zmianie z pewnością zostanie dodany. Osobiście wolę raczej zwracać uwagę tak jak Tobie, czyli normalnie wytłumaczyć dlaczego tak jest i przedyskutować podejście z daną osobą, niż zakończyć rozmowę suchym "bo tak mówi regulamin, masz się zastosować, dyskusja jest bezcelowa", co szkoda, że Ty próbujesz zrobić. Jeśli jednak tak bardzo potrzebujesz podstawy regulaminowej i żadna rozmowa z wytłumaczeniem Cię nie interesuje: punkt V.2. a w ostateczności punkt V.3.
2
komentarz 13 marca 2025 przez mokrowski Mędrzec (158,960 p.)

@Yolo, Odpowiedź Arkadiusza jest merytoryczna. Punkty regulaminu nie zawierają także wielu zapisów które miały by regulować zasady dobrego wychowania, złośliwości, działania niezgodnego z dobrymi praktykami. Wielu takich podpunktów zawierać także także nie będą. Argument o braku zapisu w regulaminie, mógłby mieć znaczenie w ... działalności gospodarczej (co nie jest zabronione, jest dozwolone), ale nie w przypadku takiego forum gdzie oczekuje się określonego zachowania w kontaktach międzyludzkich. Zapewne są i tacy którzy potrzebują jawnego zapisu że "bąków nie puszcza się przy stole" aczkolwiek zakłada się że większość o tym wie. Wie także że jeśli się zdarzą (bo wszyscy jesteśmy ludźmi), to wypada przeprosić i raczej.... tego nie robić. Zapraszając kogoś do domu, także nie wywieszasz regulaminu przed drzwiami a oczekujesz pewnego sznytu zachowań i sposobów werbalizacji przekonań i wiedzy.

Potencjał pomocy nie jest także ograniczony przez brak stosowania AI. To ma być forum osób zainteresowanych technologią/programowaniem/szeroko pojętym IT a nie oprogramowania AI zadającego pytania i odpowiadającego na pytania. W ten sposób niszczysz dorobek wielu lat rozwoju tego miejsca. Sprowadzasz je do "socjologicznego eksperymentu interakcji maszyn i ludzi", lub ścieku przerzucających się tekstami automatów. A to jest nieetyczne także w świetle treści które już tu zastałeś i dorobku wielu osób których zdania nie chcesz uwzględnić. Powie Ci o tym tak zwykły człowiek jak i profesjonalista (psycholog, socjolog,...). Ktoś kto szuka odpowiedzi na tym forum (a oczywiście bazuję na swoim doświadczeniu), oczekuje interakcji z człowiekiem. Często już wyczerpał źródło w dokumentacji/książce/AI/wyszukiwarce/...  Oczekuje także (co wypracowała cywilizacja), wyraźnego oznaczania treści "nie własnych". Oczekuje także że nie będzie się spierał z systemem który identyfikuje jak "podgrzewać dyskusję" na podstawie analizy statystycznej tekstów wątków kłótni żeby sprawdzić czy poziom mimikry automatu jest wystarczający. W takich sytuacjach, warto (nawet z czystej uczciwości) wyraźnie zaznaczać takie przypadki.

AI nie weryfikuje obiektywnie treści. Weryfikuje swoją odpowiedź z danymi w sieci by ograniczać zjawiska halucynacji (mówię o obecnym stanie zastanych implementacji). Powierzanie mu takiej odpowiedzialności lub bazowanie na niej, jest i niebezpieczne i nieetyczne. Ba, ja nawet nie uznaję odpowiedzi którą tu gloryfikujesz, za wartościową i merytoryczną :) Mam do niej szereg istotnych uwag, ale nie mam zamiaru o tym dyskutować. Choćby z tego powodu że nie ma to sensu. Bo ... z kim? Przecież Ty jako człowiek umieściłeś nie swoją odpowiedź , więc będę dyskutował z AI a chcę z człowiekiem. Kimś kto bazuje na swoich doświadczeniach konfrontowanych w świecie fizycznym. Ukształtowanym przez weryfikację wzorców realnych zachowań i realnych reakcji na nie. Osoby która realizowała działania i konfrontowała się z ich efektami. Czy jest sens dyskutowania z narzędziem (a tym jest AI)?  Nie przypominam sobie w mojej karierze, merytorycznej polemiki z wyszukiwarką, generatorem treści, chatem AI. Umieszczając takie treści, przyczyniasz się do ucinania dyskusji i demotywujesz do pogłębiania wiedzy. W tym wypadku liczy się więc jednak "kto i co wygenerowało odpowiedź". Forum to nie wyszukiwarka, system ekspercki czy "tuba AI".

Wolimy dobrze sformułowane i trafne odpowiedzi, z

Proszę, nie mów "co wolimy". To przywilej "ojców narodu" i "pasterzy prawdy". Historia uczula na takie zwroty... Ty wolisz. Mniemam raczej że to po prostu ... założyłeś. Co do mojej osoby, to błędne założenie. Ja w tym forum uczestniczę zakładając że pomagam ludziom i uzyskuję pomoc od ludzi. Moje odpowiedzi i zapytania nie są "anglosaskim porozmawiaj z moją ręką" albo "rozpocznij polemikę z młotkiem".

Moim prawem jest także ustosunkowanie się do odpowiedzi które nie są jawnie oznaczone jako wygenerowane przez automat. Tu nie ma elementu zachowania szacunku do innej osoby, jej wiedzy czy doświadczenia. Czasu jaki poświęciła na uzyskanie wiedzy i umiejętności. Mogę mieć do takich wypowiedzi osobisty stosunek bardzo krytyczny bo nikogo nie obrażam. Nie obchodzi mnie więc jak Twoje AI ocenia fakt że nie akceptuję jej wypowiedzi. Ale ... czy Ty powinieneś mieć o to pretensje? :)

Co uregulowania takich zachowań, sugeruję by prowadzący to forum, przemyśleli wprowadzenie podpunktów regulujących zachowania związane z publikowaniem treści automatycznych. Wiodące serwisy już to robią, jako minimum, wymagając ich jawnego oznaczenia. Sugeruję także zastanowić się poważnie czy takie treści powinny być dopuszczane. Doświadczenie pokazuje że ma to swoje konsekwencje. Tak praktyczne jak i socjologiczne.

1
komentarz 13 marca 2025 przez Arkadiusz Waluk Ekspert (291,410 p.)
Dzięki za Twoje spojrzenie :)

Jak wspomniałem wyżej, uważam że będzie trzeba przy najbliższej okazji wprowadzić jawnie zapisany zakaz wrzucania odpowiedzi z AI, bo to się regularnie powtarza. Nie sądzę, że dodanie opcji oznaczania wpisu generowanego przez AI ma sens. Gdybyśmy mieli jakieś rzeczy poboczne, przykładowo np. jakieś grafiki, zdjęcia, obrazki ilustrujące coś i do tego ktoś użyje sztucznej inteligencji to myślę że miałoby to jakiś sens, takie rzeczy dodatkowe można byłoby po prostu dopuścić i oznaczać. Ale w przypadku, gdy chodzi o odpowiedzi, czyli w zasadzie najważniejszą rzecz na forum, to ich generowanie w automatach nie ma wg mnie żadnego sensu.

Równie dobrze moglibyśmy zrobić też wspomnianą integracje z Chatem GPT, nawet jako dodatkowa funkcjonalność, ale to chyba też nie o to chodzi. Chat sobie będzie coś odpowiadał, później inni odpowiadający mogą się czuć niepotrzebni i uznają, że szkoda ich czasu, bo automat zawsze coś odpowie, nie zważając na to czy to jest dobre czy nie, pytający zacznie iść w tym kierunku i tak dalej.

Póki co już na teraz dodaliśmy krótkie wyjaśnienie do FAQ, aby można było linkować w razie potrzeby, gdy ktoś potrzebuje czegoś bardziej "oficjalnego": https://forum.pasja-informatyki.pl/faq#czy-mozna-uzywac-ai-na-forum
komentarz 26 marca 2025 przez TOWaD Mądrala (6,770 p.)
edycja 26 marca 2025 przez TOWaD

integracje z Chatem GPT, nawet jako dodatkowa funkcjonalność,

Myślałem wcześniej że to dobry pomysł, ale kto będzie czytał posty powyżej 300 słów i rozkminał o co chodzi autorowi pytania.

Ps. Aczkolwiek fajne było by ktoś jakoś, ogarniał i sprawdzał kod powstały z AI. Boto jak bomba dana dzieku do zabawy.

Podobne pytania

0 głosów
1 odpowiedź 346 wizyt
pytanie zadane 23 lutego 2025 w C i C++ przez whiteman808 Mądrala (5,540 p.)
0 głosów
1 odpowiedź 229 wizyt
pytanie zadane 12 listopada 2019 w Nasze projekty przez KrzysztofKord Nowicjusz (120 p.)
0 głosów
1 odpowiedź 462 wizyt
pytanie zadane 15 sierpnia 2019 w Nasze projekty przez suciorek Nowicjusz (120 p.)

93,667 zapytań

142,588 odpowiedzi

323,127 komentarzy

63,191 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

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...