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

Python - dlaczego with działa tylko raz.

0 głosów
112 wizyt
pytanie zadane 10 września 2021 w Python przez thesolitaryofchoice Początkujący (260 p.)

Witam mam banalny skrypt:

#!/usr/bin/python3

import csv
import numpy
import os

def is_equal(a, b):
    if a == b:
        return True
    
with open(os.path.join(os.getcwd(), 'warsztaty', 'warsztaty', 'srednie_wyniki_egzaminu_maturalnego.csv')) as csvfile:
    
    results = []
    readCSV = csv.reader(csvfile, delimiter=';')
    
    for row in readCSV:
        results.append(float(row[7].replace(",", ".")))
    
    mediana = numpy.median(results)
    
    print("Srodkowy wynik dla średnich wyników maturalnych to: ", mediana, "%.")
    
with open(os.path.join(os.getcwd(), 'warsztaty', 'warsztaty', 'srednie_wyniki_egzaminu_maturalnego.csv')) as csvfile:
    
    readCSV1 = csv.reader(csvfile, delimiter=';')

    for row1 in readCSV1:
        if float(row1[7].replace(",", ".")) == float(mediana):
            print(float(row1[7].replace(",", ".")))
            scores = []
            scores.append(row1[5])
            scores.append(row1[3])
            scores.append(row1[2])
            print("W roku: ", scores[0], ", z przedmiotu: ", scores[1], ", poziom: ", scores[2])    
    print(max(results))

I następujący problem, jeżeli zakomentuje 23 linię kodu instrukcje aż do 35 linii kodu się nie wykonają. Ktoś wie dlaczego po prostu Python to pomija.? Dodam, że skrypt działa w virtualenv.

Z góry dziękuję za pomoc. I za wgląd w kod.

Mateusz

3 odpowiedzi

+2 głosów
odpowiedź 10 września 2021 przez Oscar Pasjonat (22,170 p.)
Ogólnie nie znam pythona, ale tak, prawie we wszystkich językach ogólnego przeznaczenia obsługa plików jest podobna, jeśli przeczytasz plik do końca, to nie można go przeczytać drugi raz bez wykonania odpowiedniej operacji na tym pliku - ponownego otwarcia lub przewinięcia na początek.

Tak swoją drogą możesz wyznaczyć, i średnią, i medianę w jednym przebiegu pętli. Przecież zmienna readCSV się nie zmienia.
komentarz 10 września 2021 przez Wiciorny Mędrzec (199,040 p.)
ale plik wczytywany jest w bufor, który przechowuje cały plik- tak zwyczajowo się robi w językach programowania, stąd spokojnie ten bufor możesz czytać wielokrotnie, kwestia implementacji.
Każdorazowe wczytywanie do końca pliku bez trzymanai w cashe, byłoby tragiczne w skutkach i optymalizacji.
Wyobraź sobie ładowanie n-plików za każdym m razem użyć jaka to ogromna złożoność
komentarz 11 września 2021 przez thesolitaryofchoice Początkujący (260 p.)

@Oscar, To znaczy ja chciałem w tym drugim czytaniu sprawdzić w jakich sytuacjach w row wystąpi mediana. To były dla wyników matur cztery wiersze. No i musiałem przeczytać faktycznie jeszcze raz plik tak jak mówisz. Nie umiem nigdzie znaleźć póki, co potwierdzenia Twoich słów. Może powinienem wgryźć się bardziej w temat. Myślę, że rozwiązaniem byłoby gdybym umiał jedną funkcją ddziałąjącą na csvREAD wykryć wystąpienie wszystkich tych wartości w jakimś wierszu. I to miałem problem, bo wiem, że np index() zwraca pierwsze wystąpienie, nie umiałem znaleźć metody, która zwróciłaby w tablicy od razu wszsytkie wystąpienia dla jakiejś wartości str float lub int. Mam na myśli tablicę results w której przechowywałem wartości float i z której po posortowaniu metoda median wzięła medianę.

+2 głosów
odpowiedź 11 września 2021 przez profesorek96 Szeryf (88,100 p.)

Zacznijmy od początku.

Język python pozwala na obsługę plików. Plik otwierasz następnie czytasz z niego dane. Po wykonaniu tych czynności nie możesz zapomnieć o zamknięciu pliku.

Przykład poniżej otwiera plik o nazwie moj.txt następnie wyświetla jego zawartość na ekranie oraz zamyka plik:

f=open("moj.txt","r")
dane=f.read()
print(dane)
f.close()

Niestety często zdarza się, że zapomnimy o tym aby zamknąć plik. Z pomocą właśnie przychodzi instrukcja with. Nazywana jest również menadżerem kontekstu. Zobacz na poniższy przykład:

with open("moj.txt","r") as f:
        dane=f.read()
        print(dane)

Powyższy kod robi dokładnie to samo co jego  poprzednik. Zwróć uwagę, że nigdzie nie wywołuje metody close. Plik zostanie sam zamknięty po wyjściu z bloku kodu with.

Nie ma w tym żadnej magii. W momencie wejścia do metody with wywoływana jest metoda magiczna __enter__ zaś w momencie wyjścia metoda __exit__.

Jeśli chciałbyś używać obiektów swojej własnej klasy z instrukcją with musisz zadbać o to by nadpisać metodę __enter__ oraz __exit__.

Zobacz na kod poniżej:

class moja:
	def __enter__(self):
		print("Poczatek")
	def __exit__(self,type, value, traceback):
		print("Koniec")	

with moja() as f:
	print("HEJ:)")

Uruchamiając kod na ekranie zobaczyli byśmy trzy napisy. Najpierw zrealizowała by się metoda __enter__ czyli wyświetliłby się napis "Początek" Następnie wnętrze with, czyli na ekranie ukazał by się napis "HEJ". Na końcu wykonała by się metoda __exit__ powodująca wyświetlenie napisy "Koniec".

Zapraszam cię również do przeczytania tego artykułu:

https://printpython.pl/poczatki/menadzer-kontekstu-slow-kilka-o-instrukcji-with/

komentarz 11 września 2021 przez thesolitaryofchoice Początkujący (260 p.)
Dobra super, dzięki za artykuł na blogu. Zasubskrybowałem. Ale nie tłumaczy mi on raczej, dlaczego funkcja __exit__ wywołuje się po przebiegu przez pierwszą pętlę. Chyba, że ja nie umiem wychwycić tej odpowiedzi. Czy też jak w wypadku funkcji z instrukcją yield, jak to się dzieje, że po pierwszym przebiegu pętli zaraz wywoł≤a się instrukcja close()?
+1 głos
odpowiedź 10 września 2021 przez Wiciorny Mędrzec (199,040 p.)

I następujący problem, jeżeli zakomentuje 23 linię kodu instrukcje aż do 35 linii kodu się nie wykonają. 

 W 23 lini otwierasz plik, jak go nie otworzysz to jak operacje na nim mają się wykonać? 

 readCSV1 = csv.reader(csvfile, delimiter=';')

skoro robisz potem operacje na readCSV1, który czyta plik csvFIle, którego ty nie posiadasz - gdyż zmienna nie możę być poprawnie zainicjalizowana, bo nie otworzyłeś pliku który czyta dane i do niej zapisuje, więc nie może się to wykonać bo zwaraca błąd.odczyt z csvFile.  

komentarz 11 września 2021 przez thesolitaryofchoice Początkujący (260 p.)
Przepraszam, faktycznie zapomniałem dodać, że nazewnictwo nie ma tu znaczenia. To znaczy, jeśli zastąpię readCSV1 - readCSV, to i tak linie kodu poniżej się nie wykonają. To znaczy, jęsli będę chciał sprawdzić w jakich przypadkach wiersz w csc readerze jest równy, co do 8 wartości medianie, to niestety muszę jeszcze raz przeczytać plik.

Podobne pytania

0 głosów
0 odpowiedzi 55 wizyt
pytanie zadane 10 marca 2021 w Python przez cba Użytkownik (620 p.)
0 głosów
1 odpowiedź 177 wizyt
pytanie zadane 30 grudnia 2018 w Python przez XSPACE Użytkownik (690 p.)
0 głosów
1 odpowiedź 31 wizyt
pytanie zadane 21 października 2020 w Python przez poldeeek Mądrala (5,870 p.)

86,541 zapytań

135,291 odpowiedzi

300,649 komentarzy

57,288 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...