Wyjście z metody bez wywalania apki

Wyjście z metody bez wywalania apki
aksimoN
  • Rejestracja:prawie 7 lat
  • Ostatnio:10 miesięcy
  • Postów:88
0

Czysto teoretycznie czy da się wyjść z metody (pewnie się da tylko jak to robić w prawidłowy sposób) tak aby to że ona nic nie zwróci nie wywalało programu?
Mamy np. coś takiego:

Kopiuj
string nazwa  = Znajdz_nazwe(10);

chciałbym aby program jeśli metoda nie znajdzie nazwy dla 10 nie wywalał przypisania do stringa nazwa tylko wychodził z jakąś informacją.
Czyli pewnie można by było to zrobić dwojako:

  • albo jeśli metoda nic nie znajdzie to do stringa zwrócić jakiś defaultowy string, tylko wtedy muszę znowu sprawdzać czy został zwrócony defaultowy string i wtedy oprogramować dla niego jakieś ruchy
  • albo w samej metodzie oprogramować coś żeby zwróciła jakąś informację i wyszła z programu w taki sposób aby przerwała przypisywanie resultatu do stringu nazwa (jakiś break czy coś?)
edytowany 2x, ostatnio: Riddle
Qbelek
  • Rejestracja:prawie 6 lat
  • Ostatnio:2 minuty
  • Postów:102
0

Można. Co to jest to Result?

aksimoN
sorrki zapomniałem usunąć, aby dostać wynik z wynik innej metody tzn Task'a tego potrzebowałem... poprawię bo tutaj nie trzeba
Qbelek
  • Rejestracja:prawie 6 lat
  • Ostatnio:2 minuty
  • Postów:102
0

Nie jestem pewny czy o to Ci chodzi, ale możesz zrobić coś takiego np

Kopiuj
static class StringExt
{
    static string Default(this string str, string defVal) => str == null ? defVal : str;
}

string nazwa  = Znajdz_nazwe(10).Default("dupa");

Wtedy przy zwracaniu nulla z metody zwróci zamiast niego jakiś domyślny string. Albo możesz użyć Either z https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Value%20Monads/Either/Either/index.html

O co chodzi z przerwaniem przypisywania?

edytowany 1x, ostatnio: Riddle
VA
  • Rejestracja:ponad 7 lat
  • Ostatnio:3 dni
3

Czytałeś o czym takim jak sterowanie przepływem, instrukcje warunkowe itd?

kzkzg
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 21 godzin
  • Postów:925
2

Najprościej w tym przypadku to zwrócić nulla, no chyba ze null jest prawidłową wartością.
Może jakiegoś tupla:

Kopiuj
private (string result, bool success) Znajdz(int v)
{
      if (true) //dobre
      {
         return ("costam", true);
      }
         return (null, false);
}

wtedy wołasz:

Kopiuj
(string result, bool success)  = Znajdz(10);
if (success) 
 {
    Console.WriteLine(result);
}

Keep calm and blame frontend.
Tell your cat I said pspsps.
edytowany 1x, ostatnio: kzkzg
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
4
Qbelek napisał(a):
Kopiuj
    static class StringExt
    {
        static string Default(this string str, string defVal) => str == null ? defVal : str;
    }

    string nazwa  = Znajdz_nazwe(10).Default("dupa");

Doprawdy? A może lepiej:

Kopiuj
string nazwa  = Znajdz_nazwe(10) ?? "dupa";

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Qbelek
Faktycznie lepiej
AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:9 dni
  • Postów:3561
1
kzkzg napisał(a):

Najprościej w tym przypadku to zwrócić nulla, no chyba ze null jest prawidłową wartością.

Człowiek pisze o "wywalaniu apliacji" czyli pewnie zwraca nulla.

@aksimoN:

Jest wiele sposobów, NIESTETY nie wyobrażam sobie bez głębszego oswojenia z językiem, atu zwykły null jest problemem. Gorsze lub lepsze, kolejność przypadkowa

  • parametr out
  • Either
  • przemyślenie projektu obiektowego (o którym nie mówisz), połowa z potencjalnych a ELEGANCKICH możliwości by wykonywał zależny kod warunkowo, dla niepustego rezultatu,

Bo C to najlepszy język, każdy uczeń ci to powie
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0
aksimoN napisał(a):

Czysto teoretycznie czy da się wyjść z metody (pewnie się da tylko jak to robić w prawidłowy sposób) tak aby to że ona nic nie zwróci nie wywalało programu?

Skąd chcesz wyjść:

  1. Z całego programu
  2. Z pętli
  3. Z funkcji
  4. Z funkcji ale "piętro" (lub kilka) wyżej
    Ewentualnie, np zrobić continue w pętli.
Kopiuj

private string FindName(int value)
{
  const string[] Names=new String[] {"Ala","Ewa","Maria"};
  if(value<Names.Length) return Names[value];
  throw new ArgumentOutOfRangeException($"FindName: value ({value}) must be less then {Names.Length}");
}

private void Foo()
{
  String str=FindName(10);
}

private void Bar()
{
  try { Foo(); } catch(ArgumentOutOfRangeException e) { MessageAboutError(e.Message()); }
}

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 1x, ostatnio: _13th_Dragon
aksimoN
3. Z funkcji ale tak żeby przypisanie wyniku funkcji do stringa nie wywalało programu i żeby po odpowienim komentarzu przechodziło jeszcze wyżej kiedyś były jakieś labelki czy coś w C++ chodzi o to że jeśli funkcja nic nie zwróci to nie ma sensu dalsze działanie programu i chciałbym wrócić do głównego menu bez oprogramowywania 10 if'ów
_13th_Dragon
To try { throw ... } catch() {}
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:9 minut
  • Lokalizacja:Laska, z Polski
  • Postów:10056
2

Czyli masz metodę która może coś znaleźć, i wtedy chcesz coś zrobić z wynikiem, albo może czegoś nie znaleźć - i co wtedy chcesz zrobić?

Czyli w pseudokodzie, chcesz zrobić coś takiego:

Kopiuj
Coś coś  = Znajdz_nazwe(10);

if (...) {  // jakieś sprawdzenie czy znalazło nazwę
  return "Znalazłem nazwę " + coś;
} else {
  return "Nie znalazłem nazwy";
}

Więc pytanie co może być tym "czymś"?

  • Możesz zwrócić null, i wtedy musisz zrobić nullchecka: wtedy wartość znaleziona to string, a null oznacza "nie znaleziono". Możesz też zrobić parametr out albo ref, ale tak czy tak będziesz musiał coś do nich wstaw
  • Możesz rzucić i złapać wyjątek: wtedy wartość znaleziona to jest to co zwróci funkcja, a wyjątek oznacza "nie znaleziono"
  • Możesz zwrócić jakiś obiekt jak Optional/Result, którego wartość present to jest wartość znaleziona, a pusty result oznacza "nie znaleziono",
  • Możesz zrobić w obiektowym stylu swoją klasę, np FoundName z metodami isFound() oraz name(); i metoda isFound() zwraca true lub false w zależności od tego czy coś jest znalezione, i jeśli tak to name() zwraca to co jest znalezione

Dodatkowo, niektóre z tych opcji pozwalają skrócić ten zapis, np zamieniając go na ternary ?/: lub null coalesce ??, ale tak czy tak ten if tam będzie (tylko schowany).
Oprócz tego, możesz "zwrócić" wartość używając out albo ref, ale tak czy tak musisz zdecydować co tam "włożyć", albo null, albo instancje klasy.

Bardziej hardcore'owe wyjście, to np przekazanie dwóch strategii do Znajdz_nazwe, przekazując np dwie lambdy lub dwie implementacje jakiegoś interfejsu, np:

Podejście z lambdami

Kopiuj
Znajdz_nazwe(10,
  (name) => Console.Write("name found " + name),
  () => Console.Write("name not found"));

Podejście z implementacją interfejsu

Kopiuj
interface Listener {
  void nameFound(string name);
  void nameNotFound();
}

Znajdz_nazwe(10, new Listener {
  void nameFound(string name) {
    Console.Write("Name found " + name);
  }

  void nameNotFound() {
    Console.Write("Name not found");
  }
});

Te 6 wyjść to jest niestety wszystko co możesz zrobić, innej opcji oprócz nich chyba nie ma. Ja osobiście chyba wybrałbym opcje z Result albo z własną klasą.

edytowany 5x, ostatnio: Riddle
_13th_Dragon
W niektórych przypadkach linq może zadziałać ale nie zgadniemy dopóki nie powie czego chce osiągnąć.
aksimoN
  • Rejestracja:prawie 7 lat
  • Ostatnio:10 miesięcy
  • Postów:88
0

No właśnie jak nic nie znajdzie to chcę wyjść do głównego menu czyli poziom wyżej niż przypisanie wyniku funkcji, tak wiem wiem są if'y ale dużo by ich było bo jeden w samej funkcji a drugi po przypisaniu wyniku do stringa. Bo np. jeśli funkcja nic nie znajdzie to mogę zwrócić coś po czym kolejny if będzie wiedział czy obrabiamy ten wynik czy wychodzimy ale wolałbym to ogarniać jakimś przeskokiem do innego miejsca w kodzie. Może już się tak nie pisze programów z jakimiś labelkami dlatego pytam jak to się rozwiązuje prawidłowo

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:9 minut
  • Lokalizacja:Laska, z Polski
  • Postów:10056
1
aksimoN napisał(a):

No właśnie jak nic nie znajdzie to chcę wyjść do głównego menu czyli poziom wyżej niż przypisanie wyniku funkcji, tak wiem wiem są if'y ale dużo by ich było bo jeden w samej funkcji a drugi po przypisaniu wyniku do stringa. Bo np. jeśli funkcja nic nie znajdzie to mogę zwrócić coś po czym kolejny if będzie wiedział czy obrabiamy ten wynik czy wychodzimy ale wolałbym to ogarniać jakimś przeskokiem do innego miejsca w kodzie. Może już się tak nie pisze programów z jakimiś labelkami dlatego pytam jak to się rozwiązuje prawidłowo

No prawidłowo to się to rozwiązuje poprawnym kontrolą przepływu (np if, return, throw) albo polimorfizmem. Najlepiej by było jakbyś pokazał kod.

edytowany 2x, ostatnio: Riddle
aksimoN
  • Rejestracja:prawie 7 lat
  • Ostatnio:10 miesięcy
  • Postów:88
0

W głównym menu mam np:

Kopiuj
case "7":
  Console.WriteLine("Podaj nazwę aplikacji:");
  string send_appName = Console.ReadLine().Trim();
  Console.WriteLine("Wybrano przesłanie zmian: {0}.", send_appName);
  string[] send_id_and_path_a = find_id_path2("A", send_appName).Result;
  int id_a_send = Int16.Parse(find_id_path2("A", send_appName).Result[0]);
  int id_b_send = Int16.Parse(find_id_path2("B", send_appName).Result[0]);
  if (id_a_send != 0 || id_b_send != 0)
  {
      int issue_number_send = read_issues("A", id_a_send).Result;
      if (issue_number_send != 0)
      {
          string issueIid = issue_number_send.ToString();
          string issueTitle = read_issue("A", id_a_send, issueIid).Result.title;
          var title_pattern = new Regex(@"(Wniosek o przesłanie zmian)[(A-Z ,0-9\._@)]*");
          var title_match = title_pattern.Matches(issueTitle);
          if (title_match.Count == 1)
          {
              //Cos tam robi 
          }
          else Console.WriteLine("Nie znaleziono");
      }
      else
      {
          Console.WriteLine("Brak issue");
      }
  }
  else Console.WriteLine("Nie znalazłem takiej aplikacji");  //to jest else którego nie chciałem dodatkowo pisać
  Console.ReadLine();
  return true;              

a w funkcji (tasku):

Kopiuj
static async Task<string[]> find_id_path2(string repository, string AppName) //GET aplication id
{
    List<Project> projects = new List<Project>();
    List<Project> projects_all = new List<Project>();
    Project only_one = new Project();
    string[] id_and_path = new string[2];
    int page = 1;
    int number_projects_pages = 0;
    string next_page;
    do
    {
        //odpytuje i jak znajdzie to dodaje do listy projects_all
    }
    } while (next_page != "");
    if (projects_all.Count > 1)
    {
        list_project(projects_all);
        Console.WriteLine("Podaj ID projektu:");
        string project_nr = Console.ReadLine().Trim();
        Project result = projects.FirstOrDefault(r => r.id == Int16.Parse(project_nr));
        id_and_path[0] = result.id.ToString();
        id_and_path[1] = result.path_with_namespace;
        return id_and_path;
    }
    else
        if (projects_all.Count == 1)
        {
            Project result = projects_all[0];
            id_and_path[0] = result.id.ToString();
            id_and_path[1] = result.path_with_namespace;
            return id_and_path;
        }
        else {                                     //i to jest else którego nie chciałem dodatkowo pisać                      
                id_and_path[0] = ("0");
                id_and_path[1] = ("0");                
                return id_and_path;
             }           
}

Chodziło o to żeby nie trzeba było przypisywać do id_and_path ("0","0") żeby jak funkcja to zwróci nie trzeba było po wyjściu z funkcji oprogramowywać kolejnego przypadku (ostatni else) że dla tego ("0","0") ma napisać że nie znalazł i wraca do głównego menu. Chciałem już ogarnąć to na poziomie tej linii:

Kopiuj
string[] send_id_and_path_a = find_id_path2("A", send_appName).Result;

że jak nie uda się funkcji znaleźć i przypisać send_id_and_path to ma wyjść do głównego menu z komentarzem po prostu, wiem że to nie do końca prawidłowe ale mam za dużo miejsc w którym bym musiał do doprogramowywać a to tylko ja używam więc chodzi mi o to żeby było mniej klepania a jednocześnie chętnie się dowiem jak to powinno być prawidłowo rozwiązane :P

ps. z góry przepraszam za pomieszanie z poplątaniem ponieważ ja zazwyczaj robię coś aby działało i nie patrzę na to czy to jest napisane zgodnie ze sztuką ale komentarze uświadamiające mile widziane ;)

edytowany 8x, ostatnio: Riddle
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:9 minut
  • Lokalizacja:Laska, z Polski
  • Postów:10056
2
aksimoN napisał(a):

W głównym menu mam np:

[...]

Chodziło o to żeby nie trzeba było przypisywać do id_and_path ("0","0") żeby jak funkcja to zwróci nie trzeba było po wyjściu z funkcji oprogramowywać kolejnego przypadku (ostatni else) że dla tego ("0","0") ma napisać że nie znalazł i wraca do głównego menu. Chciałem już ogarnąć to na poziomie tej linii:

Kopiuj
string[] send_id_and_path_a = find_id_path2("A", send_appName).Result;

że jak nie uda się funkcji znaleźć i przypisać send_id_and_path to ma wyjść do głównego menu z komentarzem po prostu, wiem że to nie do końca prawidłowe ale mam za dużo miejsc w którym bym musiał do doprogramowywać a to tylko ja używam więc chodzi mi o to żeby było mniej klepania a jednocześnie chętnie się dowiem jak to powinno być prawidłowo rozwiązane :P

No to moim zdaniem to wygląda jak za dużo kombinowania w jednym miejscu.

aksimoN napisał(a):

ps. z góry przepraszam za pomieszanie z poplątaniem ponieważ ja zazwyczaj piszę coś aby działało i nie patrzę na to czy to jest robione zgodnie ze sztuką

Niby nie starasz się robić zgodnie ze sztuką, ale to własnie robienie zgodnie ze sztuką sprawiłoby że nie miałbyś tego problemu który teraz masz ;) Czyli ten dodatkowy else którego nie chcesz.

aksimoN
  • Rejestracja:prawie 7 lat
  • Ostatnio:10 miesięcy
  • Postów:88
0

czyli właśnie jak bo teraz nie skumałem jak to powinno być żeby nie trzeba było tych dodatkowych dwóch else'ów... jednego w tasku a jednego na koniec case'a

Jak to ogarnę to następnym razem będzie bardziej "ze sztuką"

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:9 minut
  • Lokalizacja:Laska, z Polski
  • Postów:10056
1
aksimoN napisał(a):

czyli właśnie jak bo teraz nie skumałem jak to powinno być żeby nie trzeba było tych dodatkowych dwóch else'ów... jednego w tasku a jednego na koniec case'a

Jak to ogarnę to następnym razem będzie bardziej "ze sztuką"

No jak ja to czytam, to widzę że z wyżej poziomowej części przekazujesz do niżej poziomowej części aplikacji jakieś dane, ta niżejpoziomowa część je obrabia, i zwraca jakiś default; i potem w wyżej poziomowej części znów obrabiasz te dane z dołu (albo te poprawne, albo te defaultowe); i Ty chcesz nie musieć precyzować tych defaultowych danych w niżej poziomowej części (w find_id_path2()) jak rozumiem, czy tak?

Bo jeśli tak, to moim zdaniem powinieneś zwrócić Task<Result<string[]>> z tej metody. Wtedy możesz zwrócić pustego Result, i potem na nim robić .map() w tym swoim switch'u.

Oprócz tego, kilka tipów:

  • Zamiast string[] zrób obiekt pod te dwie wartości
  • Nie używaj metod statycznych
  • Nie używaj switchów
edytowany 1x, ostatnio: Riddle
aksimoN
  • Rejestracja:prawie 7 lat
  • Ostatnio:10 miesięcy
  • Postów:88
0

W skrócie... mam główne menu, tam podaje 7 i wchodzę to tego kodu co załączyłem i teraz chodzi o 4tą linię:

Kopiuj
string[] send_id_and_path_a = find_id_path2("A", send_appName).Result;

było tak że jeśli funkcja find_id_path2 nie znalazła jakiś dwóch stringów to się wywalało na przypisaniu ich do send_id_and_path_a, ja chciałbym żeby jeśli funkcja nie znajdzie nic to zamiast przypisania wyświetliło jakiś komunikat i wróciło do głównego menu. Czy da się to jakoś skrócić do tej linii?

coś na zasadzie

Kopiuj
string[] send_id_and_path_a = find_id_path2("A", send_appName).Result ?? "Nie ma takiej aplikacji" //i tutaj wyjście z case "7"
edytowany 2x, ostatnio: aksimoN
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:9 minut
  • Lokalizacja:Laska, z Polski
  • Postów:10056
0
aksimoN napisał(a):

W skrócie... mam główne menu, tam podaje 7 i wchodzę to tego kodu co załączyłem i teraz chodzi o 4tą linię:

Kopiuj
string[] send_id_and_path_a = find_id_path2("A", send_appName).Result;

było tak że jeśli funkcja find_id_path2 nie znalazła jakiś dwóch stringów to się wywalało na przypisaniu ich do send_id_and_path_a, ja chciałbym żeby jeśli funkcja nie znajdzie nic to zamiast przypisania wyświetliło jakiś komunikat i wróciło do głównego menu. Czy da się to jakoś skrócić do tej linii?

No samo z siebie się nie da. Musisz to jakoś obkodzić. Albo ifem, albo wyjątkiem, albo polimorfizmem.

Możesz zrobić wyjątek class MissingPathException, rzucić go ze środka find_id_path2(), i złapać poza switchem.

aksimoN
  • Rejestracja:prawie 7 lat
  • Ostatnio:10 miesięcy
  • Postów:88
0

sorrki poprawiłem wyżej ale wrzucę tu, nie ma czegoś takiego??

Kopiuj
string[] send_id_and_path_a = find_id_path2("A", send_appName).Result ?? "Nie ma takiej aplikacji" //i tutaj wyjście z case "7"
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:9 minut
  • Lokalizacja:Laska, z Polski
  • Postów:10056
1
aksimoN napisał(a):

sorrki poprawiłem wyżej ale wrzucę tu, nie ma czegoś takiego??

Kopiuj
string[] send_id_and_path_a = find_id_path2("A", send_appName).Result ?? "Nie ma takiej aplikacji" //i tutaj wyjście z case "7"

Jeśli jesteś w pętli, to możesz użyć continue.

Ale to wszystko jest strasznie średnie, bo masz zbudowaną taką "strukturę" wielkiej pętli z wielkim switchem, i to nie jest dobre programowanie. Nie powinieneś myśleć o swojej aplikacji w kontekście "tutaj wyjście z case 7", tylko w kontekście tego jak aplikacja ma działać - co powinna konkretnie aplikacja zrobić w momencie, w którym nie znajdziesz tego patha w czymś w czym tam szukasz - i obkodzić to odpowiednio. Ten switch działa na Twoją niekorzyść w takim sensie że ogranicza sposób w jaki myślisz o tej aplikacji. W C# jest masa narzędzi które pozwoliłby Ci osiągnąć to co chcesz, ale nie możesz ich wykorzystać bo się przytwierdziłeś do takiej imperatywnej struktury jak pętla+switch.

edytowany 1x, ostatnio: Riddle
aksimoN
  • Rejestracja:prawie 7 lat
  • Ostatnio:10 miesięcy
  • Postów:88
0

To jak inaczej zbudować sobie menu wyboru. Wypisuję co można zrobić i z pomocą switch'a pozwalam wybierać użytkownikowi co chce zrobić. Każdy case to mały podprogram. Chciałbym umieć w każdym momencie wyjść z podprogramu żeby wrócić do menu głównego czy jak coś nie wyjdzie czy jak skończę coś robić w podprogramie.

edytowany 1x, ostatnio: aksimoN
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:9 minut
  • Lokalizacja:Laska, z Polski
  • Postów:10056
0
aksimoN napisał(a):

To jak inaczej zbudować sobie menu wyboru. Wypisuję co można zrobić i z pomocą switch'a pozwalam wybierać użytkownikowi co chce zrobić. Każdy case to mały podprogram. Chciałbym w każdym umieć w każdym momencie wyjść z podprogramu żeby wrócić do menu głównego czy jak coś nie wyjdzie czy jak skończę coś robić w podprogramie.

No i właśnie o tym mówię, w kontekście zamykania się w struktury. To nie jest żaden "podprogram", sam sobie go tak nazwałeś.

Zbuduj aplikacje metodami, wyjątkami, ifami, pętlami i polimorfizmem, i zobaczysz że Twoje problemy znikną.

Natomiast odpowiadając na Twoje pytanie

aksimoN napisał(a):

sorrki poprawiłem wyżej ale wrzucę tu, nie ma czegoś takiego??

Kopiuj
string[] send_id_and_path_a = find_id_path2("A", send_appName).Result ?? "Nie ma takiej aplikacji" //i tutaj wyjście z case "7"

Jedyne co może być propagowane "w górę" przez wszystkie warstwy do switcha w C#, to są wyjątki. Czyli robisz gdzieś throw new ExitFromCase(), a na górze catch (ExitFromCase), ale jak już mówiłem to jest dziwne - to jest Twoja próba obejścia probelmu który sam sobie stworzyłeś. Zbyt imperatywnie myślisz o tej aplikacji, tak się je tworzyło 30 lat temu.

edytowany 2x, ostatnio: Riddle
aksimoN
  • Rejestracja:prawie 7 lat
  • Ostatnio:10 miesięcy
  • Postów:88
0

No właśnie ja się uczyłem programować 30 lat temu i teraz po prostu próbuje sobie coś ogarnąć a nie chce zaczynać od podstaw... dlatego pytałem na początku ogólnikowo żeby dostać jakieś tipy jak to powinno się robić jako drogowskaz. Fakt że w sumie zapytanie było potem dość konkretne

Ja to tylko tak nazwałem podprogram bo nie umiem się precyzyjnie wysławiać. Mam metody, mam ify i pętle, nie ogarniam wyjątków i polimorfizmu. Myślałem żeby każdy wybór z menu był oddzielną metodą (podprogramem) ale też chyba nie o to Ci chodzi...

W sumie prawie każdy wybór w głównym menu zaczyna się od sprawdzenia czy jest takie send_id_and_path_a jeśli nie ma to ma o tym powiadomić zakończyć i zacząć od nowa...

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:9 minut
  • Lokalizacja:Laska, z Polski
  • Postów:10056
0
aksimoN napisał(a):

No właśnie ja się uczyłem programować 30 lat temu i teraz po prostu próbuje sobie coś ogarnąć a nie chce zaczynać od podstaw... dlatego pytałem na początku ogólnikowo żeby dostać jakieś tipy jak to powinno się robić jako drogowskaz. Fakt że w sumie zapytanie było potem dość konkretne

Ja to tylko tak nazwałem podprogram bo nie umiem się precyzyjnie wysławiać. Mam metody, mam ify i pętle, nie ogarniam wyjątków i polimorfizmu. Myślałem żeby każdy wybór z menu był oddzielną metodą (podprogramem) ale też chyba nie o to Ci chodzi...

No możesz w taki sposób to zrobić... tylko wtedy w podprogramie musisz napisać else :D

Ty próbujesz dodać jakiś mechanizm "wychodzący", który umie oddać kontrolę przepływu do funkcji wyżej - i w takim podejściu jakie prezentujesz, to nie da się tego prosto zrobić, bo nałożyłeś na swój program zbyt sztywne ramy.

aksimoN napisał(a):

W sumie prawie każdy wybór w głównym menu zaczyna się od sprawdzenia czy jest takie send_id_and_path_a jeśli nie ma to ma o tym powiadomić zakończyć i zacząć od nowa...

No to tutaj się pojawia pytanie czy ta odpowiedzialność wyciągania send_id_and_path_a jest odpowiedzialnością globalną (całościową), czy są zależne od każdego z "podprogramów", i po prostu tak się złożyło żę są wycigane. Jeśli to pierwsze, to mógłbyś pomyśleć o wyciąganiem send_id_and_path_a wczesniej; jeśli tak sie złożyło to zostaw tak jak jest.

Masz gdzieś cały ten kod na githubie?

edytowany 2x, ostatnio: Riddle
AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:9 dni
  • Postów:3561
2
aksimoN napisał(a):

W głównym menu mam np:

Kopiuj
case "7":

ciach

Kopiuj

Ty nie masz problemu z "wyjściem z metody". Ty masz projekt do zaorania. tego nie da się w ekonomiczny sposb "ulepszyć".

Ale przynajmniej już wiesz, że cała ta brzydka teoria, jakieś polimorfizmy (@Riddle +1), jakieś wzorce, separacja kodu / danych / prezentacji, jakieś książki 700+ stron powaznych autorów ... to nie wymysł idiotów na amerykańskich uniwersytetach, ale konieczność w projektach większej skali.

Kosztowna nauka, ale zawsze nauka, w następnym projekcie będziesz wiedział.

ps. nie włączam się w dyskujsję nt "odpowiedzialności atomowej jednej funkcji", której nazwa składa się z kilku spójników. To nie ma sensu w szerszym kontekście.


Bo C to najlepszy język, każdy uczeń ci to powie
edytowany 3x, ostatnio: AnyKtokolwiek
Zobacz pozostały 1 komentarz
AK
No ale co mam ci powiedzieć? W dobrze zaplanowanej architekturze takie rzeczy ("dokładanie") są łatwe, jest na nie przygotowana "szufladka", w tej chwili mi strzeliło: jak A,B,C w paczkomacie. Jak architektury nie ma,. jest ręczna praca z każdym przypadkiem oddzielnie - i po kilku takich incydentach robi się spaghetti. Ten paczkomat ma fleksem wycinane i zaspawywane otwory różnych rozmiarów z różnych stron.
AK
... pogłaskać po główce "skoro robisz dla siebie, to rób nadal tak samo" ?
aksimoN
nie, ale rady typu przeczytaj książkę 700+ to rada z d**y
AK
no masz rację, jak masz doświadczenia sprzed 30 lat to nie musisz niczego sie uczyć. ps. strasznie dawno nie widziałem słowa "podprogram" jak w tym wątku.
aksimoN
nic takiego nie napisałem że nie muszę się niczego uczyć, ale twoja odpowiedź jest totalnie nie w temacie, ja pytam o jedno a ty się czepiasz całkiem czegoś innego
aksimoN
  • Rejestracja:prawie 7 lat
  • Ostatnio:10 miesięcy
  • Postów:88
0

nie mam tego na githubie, bo tam za dużo danych wrażliwych, ja sobie po prostu oskryptowuję rzeczy które muszę w pracy wykonywać ręcznie przez wyklikiwanie

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:9 minut
  • Lokalizacja:Laska, z Polski
  • Postów:10056
2
aksimoN napisał(a):

nie mam tego na githubie, bo tam za dużo danych wrażliwych, ja sobie po prostu oskryptowuję rzeczy które muszę w pracy wykonywać ręcznie przez wyklikiwanie

No to moja rada:

  • zamień switcha na if
  • podziel cały kod na małe metody
  • zwróć Result ze swojego find_id_path2
aksimoN
i to jest rada od której można zacząć zmiany
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)