wokalove / PublicTransportApp

bus and tram routes app
1 stars 0 forks source link

Uwagi #2

Open MarcinCiura opened 4 years ago

MarcinCiura commented 4 years ago
  1. Katalog .vscode wyrzucić (1. rozdział).
  2. Albo import tkinter as tk, albo (ekhm, ekhm) from tkinter import *. Z używania przez Panią tk.Button itp. wynika, że drugie można wyrzucić.
  3. Nazwy metod i zmiennych w snake_case (2. rozdział).
  4. Wokół = spacje w normalnym kodzie, ale nie przy przekazywaniu argumentów itp. Pylint chyba to wykrywa.
  5. Skróty butnew, Win1, getAns itp. są niedobre (2. rozdział).
  6. Za długie wiersze podzielić (2. rozdział).
  7. Pisać {} zamiast dict().
  8. W klasie Traveler jest zmienny atrybut klasowy journeyCosts. Niedobrze (3. rozdział).
  9. Klasa Error na samą górę.
  10. Lepsze nazwy stałych z cenami to FULL_PRICE i REDUCED_PRICE.
  11. Takie sterowanie przebiegiem programu przez wyjątki, jak w Traveler.ticketCosts, jest nadmiarowe i mylące. Zamiast go rzucać i łapać, wystarczy else:.
  12. To samo, co np.sum(), robi sum().
  13. Tutaj i dalej w podobnej sytuacji lambda szkodzi. Moim zdaniem nic się nie wykonuje. Powinno być command=self.combine_func(...).
  14. Jeśli klasa Win2 dziedziczy z Win1 (i Win3 z Win2), a nie wywołuje konstruktora rodzica, to coś jest nie tak. Przypuszczam, że chce Pani zrobić klasę WindowBase ze wspólnymi metodami, i z niej niech dziedziczą Win1, Win2 i Win3.
  15. Z ('Courier', 12) zrobić nazwaną stałą. Podobnie BACKGROUND = 'white' i FOREGROUND = 'black'.
  16. Tutaj nie rozumiem, po co jest str(i). Jak wyglądają numery linii wczytane z bazy? W zależności od odpowiedzi, powinno się udać usunąć cudzysłowy przez int(line_number), line_number.strip('"') albo coś podobnego.
  17. Tutaj wystarczy if line_number: (puste kolekcje są fałszywe).
  18. Tutaj warto skorzystać z ', '.join(final_stops[::-1]), czy jakoś tak.
  19. Tutaj nie rozumiem kilku rzeczy:
    • wygląda na to, że do newdict są wstawiane połączenia daną linią między parami sąsiednich przystanków — w porządku, tylko że z Pani maila zrozumiałem, że pamięta Pani połączenia daną linią między wszelkimi parami przystanków na tej linii;
    • zamiast key i values lepsze będą line_number i stops;
    • jakiego typu są values[i]? czy str() jest konieczne?
    • na ile rozumiem first.translate(...), chodziło Pani np. o first.replace('[', '').replace(']', '') albo first.strip('[]');
    • zamiast newdict[first].update({k: v}) lepsze będzie newdict[first][k] = v.
  20. Znajdowanie najkrótszych ścieżek raczej nie powinno być zajęciem klasy Win2. Wyekstrahować (4. rozdział).
  21. W graf.py mimo jego jednorazowości wolałbym powsadzanie kodu do funkcji.
  22. Główna zaleta JSON-a to to, że da się go czytać. Gdyby nie nacisk na czytelność pliku z danymi, mogłaby Pani użyć modułu pickle (tutaj nie polecam, lepiej mieć czytelność). Z tym, że JSON-a całego zapisanego w jednym wierszu, tak jak jest teraz, czytać się nie da. Przypuszczam, że da się to naprawić parametrem indent do json.dump().
MarcinCiura commented 4 years ago
  1. # -*- coding: utf-8 -*- to zaszłość z Pythona 2. W Pythonie 3 nic nie robi. Przydać by się mogło tylko, gdyby używała Pani przedpotopowego edytora, w którym domyślne kodowanie to nie UTF-8.
MarcinCiura commented 4 years ago
  1. Pani kolega Dydek123 się wycwanił i postanowił użyć gotowych narzędzi do szukania ścieżek. Nie jest to głupi pomysł, tym bardziej, że własne szukanie niezbyt mu wychodziło. W związku z tym ma Pani wolną rękę: albo używa własnego find_shortest_path(), albo biblioteki networkx, albo python-igraph. Dodam tylko, że 14. przykazanie programisty/programistki brzmi: "If it ain't broke, don't fix it".
wokalove commented 4 years ago

Dzień dobry!

  1. Poprawione
  2. Poprawione
  3. Poprawione
  4. w trakcie
  5. Poprawione
  6. w trakcie - ma Pan na myśli wiersze wszystkie które są za długie, czy np. tylko te dotyczące konfiguracji buttona?
  7. Poprawione
  8. Czy jeśli zmieniłam journeyCosts na prywatny atrybut i potem koszty podróży zwrócę za pomocą metody get_Ticket_Costs, która ma dostęp do tego atrybutu dzięki temu, że jest metodą klasy i ma dostęp do prywatnych pól to to będzie nadal źle? Chodzi Panu o hermetyzaję danych? Ogólnie w przypadku dojazdów pośrednich jeśli są 3 przysiadki(bilety nie są czasowe tylko jednoprzejazdowe) to dodaję do tej zmiennej 3*wybrany bilet (studencki lub zwykły), dlatego ta wartość się tam zmienia.
  9. Poprawione
  10. Poprawione
  11. Poprawione. Zgodzę się, że ten wyjątek wepchnęłam na siłę. Czy w przypadku tego programu wymagane jest w ogóle rzucanie i łapanie wyjątków? Robiłam to głównie na potrzeby wymagań Pana Gąciarza.

12.Poprawione. Faktycznie, z przyzwyczajenia do biblioteki numpy z labolatoriów nawet na to nie wpadłam! :)

  1. Lambdy robiłam ze względu na to, że Pan Gąciarz pisał, że jeśli chodzi o Buttony to warto je tam stosować. Potem rzeczywiście zaczęłam szukać, czy taką praktykę się stosuje i właśnie w moim programie one zdają egzamin. Właśnie jak próbowałam robić bez lambd to efekty nie spełniały moich oczekiwań - czasami nawet funkcja na buttonie w ogóle nie chciała się bez niej wykonać i tutaj mówię o funkcjach typu " Wyświetl napis helllo World". Zaczęłam szukać w internecie jak ktoś obszedł podobny problem do mojego i właśnie zastosował labdy na buttonie i dopiero wtedy mi to zadziałało, także nie mam pojęcia jak to inaczej obejść. :(

  2. Czyli mam rozumieć, że nie ma być dziedziczenia "hierarchicznego"? Postaram się to zmienić.

15.Stałe stworzyć jako globalne dla wszystkich klas,czy dla przykładowo każdej klasy osobno? Wydaje mi się, że lepiej będzie dla każdej klasy osobno zdefiniować kilka takich wartości (które rzeczywiście się nie zmieniają), dlatego, że u mnie rozmiar czcionki w programie, czy kolory akurat ulegają ciągłym zmianom. Czcionki się zmieniają chociażby dlatego, że jak wywołuję Label'a, który wypisuje przystanki, a tych przystanków jest jakieś 30 to przy czcionce rozmiaru 20 nie ma szans, żeby mi się to zmieściło. A kolorki się zmieniają, żeby nie było smutno, żmudno i monotonnie. :)

  1. Numery liniii wczytane z bazy wyglądają tak: [('469',), ('439',), ('164',), ('608',), ('511',), ('304',), ('139',), ('503',), ('208',), ('179',), ('501',), ('292',), ('192',), ('169',), ('159',)] i właśnie dzięki linijce kodu str(i)[2:-3] wyświetlają się jako '469','439'...(chodziło o obcięcie zarówno nawiasów, jak i apostrofów). Próbowałam to robić int(i), ale nie działało. Teraz spróbowałam split na tej zmiennej i pokazuje mi, że nie ma takiego atrybutu. Ten fragment kodu służy tylko do wyświetlenia liniii użytkownikowi w przypadku dojazdów bezpośrednich, żeby sobie wybrał spośród nich i wpisał do pola, którą linię chce dojechać. 17.Poprawione. Racja! Mój zapis był trochę bez sensu. 18.Poprawione. Ale super! Od razu wzięłam to do przystanków w drugą stronę.

  2. --> Chodziło mi dokładnie o to co Pan napisał, ale nie wiedziałam jak to ubrać dobrze w słowa. Ogólnie jak pisałam tego maila ciężko mi było pozbierać myśli, bo miałam w głowie cały czas " Muszę napisać jeszcze to i to " i przez to mogłam coś poprzekręcać. Proszę wybaczyć czasem chaotyczne wiadomości - wynika to z pewnego rodzaju "nieobycia" jeszcze w tej terminologii programistycznej i czasem też mojego roztrzepania. --> jasne, poprawione. Dużo robiłam zmiennych roboczych, na szybko - póki pomysł nie wyleci z głowy. --> (teraz już values są jako stops) są wczytywane w formie listy, w sensie KAŹDY stop jako OSOBNA lista (trochę mnie to zdzwiło) - ale takie rezultaty otrzymuję z tej części dotyczącej sql-a. Nie do końca wiedziałam na początku jak to obejść, zeby wczytywało jako po prostu listę przystanków, a nie "listę w liście", więc po prostu przekonwertowałam tak, zeby stamtąd brało tylko stringa, czyli samą nazwę przystanku. Także w tym wypadku str(stops[i]) mi się bardzo przydał. --> Tak, to jest usuwanie nawiasów. Ogólnie chciałam tam zastosować strip albo replace, ale z niewiadomych przyczyn (dla mnie) nie chce mi to działać, więc stąd wykorzystanie first.translate(...). Jak dawałam przykładowo "first.replace('[', '').replace(']', '')" to w ogóle mi nie wyszukiwało przystanków. Pamiętam,że tkwiłam w tym punkcie długo, aż w końcu natknęłam się na "translate" i to jako jedyne rozwiązało problem.

  3. Rozumiem i też mi się to strasznie niepodoba, ale proszę mi wierzyć - siedziałam nad tym z 4 h jak nie więcej. Przekazywałam wszystkie inputy użytkownika do klasy 3 okna - sprawdzałam kilkukrotnie, czy na pewno je dobrze przekazuję i czy "są widoczne" i możliwe do użycia w klasie - z tym było w porządku. No to sobie zaimplementowałam te funkcje na 3cim oknie do wyszukiwania drogi i nie było żadnej akcji, nic nie działało. Ogólnie nie znalazłam dużo dobrych informacji na temat wielu okien w bibliotece Tkinter, więc już z bezsilności dałam na 2gie okno. Czy jeśli by tak zostało to jest bardzo dyskwalifikujące?

  4. Jasne, poprawiłam. Mogę wrzucić w postaci funkcji, ale nigdzie niewywołanej? ( z racji tego, że za pomocą graf.py stworzyłam już wcześniej ten plik. Baza nie jest aktualizowana w żaden sposób to uważam, że nie ma potrzeby go ciągle na nowo tworzyć.)

  5. To mnie Pan zaskoczył w sumie, bo ja normalnie czytam te dane właśnie z pliku .json i wyszukuje mi te połączenia.Ze względu na czytelność wybrałam .jsona - jedyne co tam musiałam zmienić to to żeby czytało w utf-8, bo nie czytało mi poprawnie polskich znaków. Ale ten algorytm normalnie działa na tym pliku i generalnie sprawdzałam na stronach typu "Jak dojadę" to często się pokrywają te pośrednie połączenia. Niestety, mam starą bazę, więc sporo z tych połączeń zostało usuniętych albo zmodyfikowanych, więc głównie weryfikowałam poprawność na podstawie podobieństw i analizowania algorytmu.

23.Poprawione. Korzystam ze Spydera, a on z automatu daje tę linijkę kodu :)

  1. Sprytne! Aczkowliek przykazań nie powinno się łamać to zostanę chyba przy swoim algorytmie, haha. Tak zupełnie szczerze - mogłabym to przerobić, ale jak sobie pomyślę ile pracy, szukania i pytań mnie to kosztowało to wolę zostawić. Dobrze jednak, że mi Pan o tym napisał, bo w wakacje mam zamiar sobie jeszcze coś w stylu wyszukiwania dróg napisać, także biblioteka jak najbardziej się przyda.

Ufff, wyszło całkiem długie wypracowanie. Dziękuję za wszystkie poprawki, dużo mi dają i mam nadzieję,że będę takich błędów popełniać coraz mniej. Pozdrawiam!

MarcinCiura commented 4 years ago

Dziękuję za zmiany i za odpowiedź. Już teraz kod wygląda dużo lepiej.

  1. Wszystkie za długie. W Google najsensowniejszy argument za 80-znakowym limitem szerokości dotyczył niewidomych programistów, którzy korzystają z takich dostawek do klawiatury z wypustkami w alfabecie Braille'a do czytania kolejnych wierszy. Te dostawki mają szerokość 80 znaków.
  2. Tu nie chodzi o hermetyzację, tylko o to, że atrybut journeyCosts się przyczepiał nie do obiektu klasy, tylko do klasy, a tak być nie powinno. Ale dobrze, że Pani wspomniała o hermetyzacji. Dodam do Poradnika punkt o niepotrzebności getterów i setterów w Pythonie. Zamiast nich można albo: a) swobodnie czytać i pisać atrybut journey_costs, przy czym przy czytaniu samej go sobie sumować (zgadzam się, że niezbyt eleganckie), albo: b) zrobić atrybut _journey_costs z getterem, który je sumuje, i spowodować za pomocą odpowiedniego dekoratora, że odczyt pseudoatrybutu ticket_cost zostanie do niego przekierowany. Na marginesie: w snake_case ma nie być żadnych wielkich liter.
  3. Nadal mam nadzieję, że projekty moich grup ja będę oceniał. Gdyby nie, to biorę na siebie Pani obronę. Na siłę jest bez sensu.
  4. Te lambdy, co zostały, są OK. Mnie chodziło o taki fragment: tk.Button(command=lambda: self.combine_func(fn1, fn2)). Ponieważ wywołanie self.combine_func() zwraca tzw. domknięcie (closure), czyli po prostu obiekt, który potem można wywołać, działało to tak samo jak lambda: jakaś_funkcja, co przy wywołaniu zwraca nieciekawy wynik — obiekt funkcji jakaś_funkcja. Żeby jakaś_funkcja się wywoływała przy wykonaniu command, trzeba napisać albo lambda: jakaś_funkcja() (czyli u Pani dopisać () po self.combine_func(fn1, fn2)), albo po prostu jakaś_funkcja, co jest prostsze i o co mi chodziło.
  5. Win2 i Win3 nie są udoskonaleniem Win1, tylko raczej jego równorzędnymi braćmi, prawda?
  6. Ma Pani rację: skoro w różnych klasach jest różnie, niech mają swoje własne stałe.
  7. Dziękuję za przykład, teraz rozumiem. Przyczyna tych komplikacji leży w .fetchall(). Standardowy sposób robienia SELECT-ów jest taki:
    line_numbers = []
    for row in cursor.execute(
        """
        SELECT LineName FROM StopDepartures
        WHERE ... ?
        AND ?
        """,
        (a, b)):
    line_numbers.append(row[0])
    # Prosi Pani SELECT-em o 1 kolumnę, więc
    # w każdym wierszu dostaje 1-elementową krotkę.
  8. Znowu zamiast zamieniać wszystko na napisy do ostrzyżenia z niepotrzebnych znaków, lepiej się przyjrzeć temu, jak wygląda lista przystanków w JSON-ie. A wygląda tak: [["Bronowice"], ["Mistrzejowice"], ["Miśnieńska"], ["Głowackiego"],.... Więc stops[i] zwraca np. ["Bronowice"] i żeby z tego wyciągnąć to, co chcemy, wystarczy stops[i][0]. ALE: JSON z listą jednoelementowych list napisów zamiast z listą napisów jest dziwny. A jest taki, bo w graph.py też Pani użyła .fetchall(). Teraz, kiedy Pani już wie, jak się obchodzić z SELECT-ami, jest świetna okazja do spowodowania, żeby graph.py robił lepszego JSON-a. Samodzielnym ćwiczeniem niech będzie dostosowanie make_graph_from_dict() do takiego lepszego JSON-a.
  9. Cieszę się, że Pani walczy. Chodzi mi o to, żeby funkcja find_shortest_path() leżała poza jakimikolwiek klasami, bo ona jest przydatna w ogóle, a nie tylko w oknie Win2 czy Win3. To łatwo zrobić. Potem powinna Pani znowu zamienić dziwne operacje na napisach pod koniec tej funkcji na porządne indeksowanie. W razie problemów proszę mi napisać, jak wygląda przykładowe shortest_way przed przeróbkami.
  10. Patrz 19.
  11. Mnie chodziło tylko o to, że w razie czego człowiek może zajrzeć do JSON-a i zobaczyć, co w nim siedzi. Kiedy cały JSON jest w jednym wierszu, jest to średnio wygodne.
  12. (24, nie 23. Automatyczne numerowanie list jest głupie.) Bardzo dobrze. Właśnie o to chodziło w przykazaniu: "Jak działa, to nie naprawiaj."
MarcinCiura commented 4 years ago
  1. Dodane.
wokalove commented 4 years ago
  1. Poprawione. Zrobiłam tak, ze te linie po prostu podzieliłam. Zamiast: funkcja(argument, argument1,argument2)

Zrobiłam: funkcja(argument, argument1, argument2)

(nie wiem jak to sformatować w kod, bo mi wrzuca do jednej liniii)

Czy o to chodzi?

  1. Zahermetyzowałam journey_costs. Poprawiłam te duże litery na małe. Jeśli chodzi o decodery to na bazie przykładów znalezionych w internecie wiem o co z nimi chodzi, ale nie do końca rozumiem jaką u mnie by miało funkcję spełnić. Mogłabym zrobić @ticket_costs na funkcji get_ticket_costs ,tylko , że jest taka sprawa, że ja właśnie nie chcę za każdym razem wywoływać funkcji ticket_costs , a zastosowanie tego dekoratora tutaj chyba z tym by się wiązało. Nie chcę dlatego, że ja w konkretnych miejscach programu, zeby obliczyć wartość biletu po prostu wywołuję tę funkcję w każdym nowym połączeniu i ona dolicza np 4.60 zł za każdym razem (przejazd z punktu A do B - 1 bilet, z B do C - drugi bilet). Za to get_ticket_costs mi po prostu zwraca łączną sumę do labela - ta funkcja w zasadzie jest mi potrzebna tylko do wyświetlania. W momencie kiedy dam @ticket_costs to to sprawi, ze jeden bilet będzie doliczony "nadmiarowo" - będzie o jeden bilet za dużo. Czy to błędne myślenie i jednak nie do końca rozumiem o co chodzi?

  2. Poprawione. Tak, zorientowałam się dopiero jak Panu napisałam maila, że w zasadzie to combine_func nic nie robi i tak jak Pan napisał, można po prostu wywołać jedną funkcję - pamiętam, że wtedy nie do końca wiedziałam jak działa przełączanie się między oknami i chciałam dołożyć tam dodatkową akcję, ale teraz widzę jakie to myślenie było bez sensu. Wyrzuciłam całkowicie tę funkcję :)

  3. Tak, dokładnie. Z tym, że niektóre metody nadpisuję w innych klasach, bo chcę, zeby trochę inne rzeczy czasem robiły, ale generalnie one są zbliżone do siebie.

  4. Poprawione.

  5. W trakcie - czyli tak jakby ten fetchall w graf.py traktuje 'Bronowice' jako kolumnę i dlatego wsadza ją jako listę? Czyli to, ze tak zapisuje mi się do tablicy to jest wina fetchalla, a nie źle sformułowanego SELECTu?

  6. Z find_shortest_path poprawione. Indeksowanie w trakcie.

  7. W trakcie

PS Dostałam kiedyś podobnie brzmiącą radę od pewnego muzyka, że własnie " Nie należy naprawiać tego co nie jest zepsute" i "Lepsze jest wrogiem dobrego" Dobrze brzmi po angielsku: "The Best Is The Enemy Of The Good"

MarcinCiura commented 4 years ago
  1. Tak, o to chodzi. Kilkuwierszowe kawałki kodu zamieszcza się tak:
    ```python
    def f(g):
        return g
  2. Tutaj i niżej przypisywanie tego do cost jest zbędne (a i tak przypisuje się do niego None). To, że dwie metody mają podobne nazwy, rodzi zamieszanie. Ja bym get_ticket_costs() przemianował np. na total_cost() i oznaczył jako @property, po czym tutaj napisał tak:
    if choice in ("yes", "no"):
    return self.total_cost
    else:
    return 0.0

    W clear_costs_of_journey() wyrzucić wyraz return, co i tak zwracał None. Wracam jeszcze do sprawy __journey_costs, które nie powinny być inicjalizowane tak, jak teraz (wyrzucić), tylko przez

    def __init__(self):
    self.__journey_costs = []

    Po zmienieniu ich inicjalizacji proszę jeszcze raz przeczytać w 3. rozdziale punkt o atrybutach klas i atrybutach instancji klas — może tym razem "zaskoczy".

  3. Zgadza się. SELECT musi być, jaki jest, a o .fetchall() najlepiej zapomnieć.

Swoje poprzednie wpisy w Issues może Pani edytować. Nie ucięło Pani ostatnich punktów, tylko je idiotycznie przenumerowało.

wokalove commented 4 years ago

Przepraszam za to, że się dłużej nie odzywałam, ale uczyłam się do kolokwium z JS i piszę też inne projekty.

  1. Settery i gettery przerobione na property, poprawione też to bezsensowne przypisywanie, które i tak nie było do niczego potrzebne, czyszczenie kosztów podróży też naprawione. Dopóki mi Pan nie napisał o dekoratorach to nie wiedziałam nawet, że coś tak fajnego istnieje w Pythonie, dziękuję.
  2. Napisałam też test do tej klasy. 3.Zmieniłam kod w tworzeniu grafu(żeby nie było tych zbędnych nawiasów). W zasadzie zrobiłam to w oparciu o Pana poradnik - ta metoda z pętlą bez .fetchall()działa bez zarzutów. Muszę jeszcze trochę kod zmienić,żeby się dobrze tworzył ten finalny graf.
MarcinCiura commented 4 years ago

Dziękuję za wiadomość. Plik testy.py proszę przemianować na MPK_test.py i po uporaniu się z innymi przeróbkami dopisać do niego ze dwa testy funkcji find_shortest_path() na jakimś prościutkim grafie.

wokalove commented 4 years ago

Dzień dobry!

  1. Przemianowałam.
  2. Zrobiłam przeróbki w funkcjach związanymi z grafami i ogólnie wszędzie jak wczytuję cokowliek z bazy to za pomocą pętli, a nie .fetchall().
  3. Dopisałam już 2 testy - stworzyłam graf dokładnie o takiej strukturze jak jest w moim programie i zrobiłam test , żeby wyszukiwał drogę z jedną przesiadką i dwoma. Pozdrawiam!
wokalove commented 4 years ago

Jeszcze mam pytanie: Czy będąc u Pana w grupie należy przesłać projekt na elfa Panu Gąciarzowi, czy po prostu każdy z Panów ocenia swoje grupy?

MarcinCiura commented 4 years ago

Dzień dobry, dziękuję za wiadomości. Niedługo zrobię kolejną rundę oglądania Państwa programów. Co do projektu — proszę go przesłać na elf zgodnie z wytycznymi dra Gąciarza. Również jeśli to ja będę oceniał projekty z moich grup, jakiś ślad w elfie powinien pozostać.

MarcinCiura commented 4 years ago

Jest nieźle. Cieszę się, że Pani się nauczyła innego podejścia do wyciągania danych niż przez napisy do oskubania ze znaków. Tylko parę drobiazgów i będzie po wszystkim.

  1. Importy w MPK.py proszę posortować: json < sqlite3 < tkinter, a potem numpy < PIL.
  2. To zbędne.
  3. Tutaj dodać wiersz odstępu.
  4. To wydaje się nieużywane. W każdym razie powinno albo przyjmować self, albo być oznaczone jako @staticmethod, inaczej nie zadziała.
  5. W testach też proszę powkładać trochę pustych wierszy. Pylint chyba podpowiada, gdzie powinny być.
  6. Ten test proszę rozbić na dwa — a to dlatego, że niepowodzenie asercji przerywa działanie metody, więc w obecnym stanie gdyby pierwsza asercja była fałszywa, nigdy byśmy się nie dowiedzieli, co z drugą.
wokalove commented 4 years ago

Dobry wieczór! Wszystko poprawione, dziękuję za wskazówki! :) Dzięki nim naprawdę bardziej podoba mi się ten projekt.

Mam jeszcze kilka drobnych pytań:

  1. Co gdy jednak mój projekt hipotetycznie sprawdzi Pan Dr Gąciarz i może się nie spodobać i przez to hipotetycznie mi nie zaliczy? Teoretycznie tego projektu jak i wielu innych osób nie ma w spisie tematów projektów u Dr Gąciarza. To będzie równoznaczne z poprawką we wrześniu?
  2. Czy wstawiając projekt na elfa muszę również wstawić raport, który Pan Gąciarz wymaga?
  3. Czy będę mogła już wstawić jakoś przed 16 czerwca projekt na elfa, żeby móc przystąpić do egzaminu w terminie zerowym?

Przepraszam jeśli męczę, ale wolę pytać, żeby później nie mieć wątpliwości. Dobrej nocy!

MarcinCiura commented 4 years ago

Zaliczone! Gratuluję, jest Pani dwudziesta w kolejności.

  1. Tak, proszę wstawić na elfa również raport. 1,3. Tak, proszę to zrobić jak najszybciej. Pod koniec tygodnia zaloguję się na elfa i wpiszę zaliczenia z projektów tym osobom, którym je przyznałem na podstawie oględzin kodu na githubie.
wokalove commented 4 years ago

Dziękuję pięknie! Bardzo się cieszę, szczególnie, że to mój pierwszy większy projekt. Pozdrawiam serdecznie :)