Liczenie średniej pyspark

Liczenie średniej pyspark
FB
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 2 lata
  • Postów:25
0

Hej,
Nie mogę sobie poradzić z obliczeniem średniej w pyspark. Muszę ją policzyć wykorzystując tylko DataFrame API, nie mogę korzystać z spark.sql.

Efekt musi być taki:

screenshot-20211228234223.png

Robię tak:

Kopiuj
spdf.select(spdf.Emission).avg().show()

ale dostaję error:

Kopiuj
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/site-packages/pyspark/sql/dataframe.py", line 1660, in __getattr__
    "'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
AttributeError: 'DataFrame' object has no attribute 'avg'

I nie bardzo czaje o co chodzi. Ktoś pomoże? :)

Spine
  • Rejestracja:około 22 lata
  • Ostatnio:minuta
  • Postów:6693
2

Nie robiłem w tym, ale według tego co znalazłem na SO, takie coś może zadziałać:

Kopiuj
spdf.select(spdf.Emission).groupBy().avg('Country').show()

https://stackoverflow.com/a/61759499/1639851


🕹️⌨️🖥️🖱️🎮
edytowany 2x, ostatnio: Spine
FB
czemu średnia z Country - to jest string
FB
chyba, że ja ten kod źle intepretuje
Spine
Popróbuj. Pewnie masz rację. Tylko nie wiem, czemu na SO nie ma parametru w groupBy. W normalnym zapytaniu byśmy grupowali po państwach, żeby obliczyć dla nich średnie emisje. Spróbuj w groupBy dać parametr 'Country', a w avg 'Emission'. Na SO w swojej odpowiedzi użył string, więc napisałem analogicznie. Nazwa kolumny jako tekst.
FB
próbowałem chyba wszystkie kombinacje i nie działa :(
ledi12
  • Rejestracja:prawie 6 lat
  • Ostatnio:2 miesiące
  • Lokalizacja:Wrocław
1
Kopiuj
from pyspark.sql import functions as F
eventsDF.select(F.avg(F.col("Emission")).alias("average"))

Policzy avg dla całej tabeli


Robię http response status cody w martwych ciągach
Spine
Miało być bez modułu sql. Samo dataframe.
ledi12
No to jest dataframe :D To nadal część api. Koledze pewnie chodzi o zwykły sql sparkowy, gdzie wywołuje się kwerendy.
FB
hmm w poleceniu mam tylko tak: "Możesz użyć tylko DataFrame API (nie możesz tego wykonać z użyciem spark.sql(...) " Czyli rozumiem, że to co podałeś jest ok?
FB
to errorem sypie :(
FB
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 2 lata
  • Postów:25
0

@ledi12:

Kopiuj
21/12/28 06:01:59 ERROR Executor: Exception in task 0.0 in stage 7.0 (TID 7)
org.apache.spark.api.python.PythonException: Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/worker.py", line 619, in main
    process()
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/worker.py", line 611, in process
    serializer.dump_stream(out_iter, outfile)
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/serializers.py", line 259, in dump_stream
    vs = list(itertools.islice(iterator, batch))
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/util.py", line 74, in wrapper
    return f(*args, **kwargs)
  File "lab4.py", line 18, in <lambda>
    df = df.map(lambda x: (x[0].strip(','),x[1].strip(','),x[2].strip(','),x[3].strip(',')))
AttributeError: 'NoneType' object has no attribute 'strip'

        at org.apache.spark.api.python.BasePythonRunner$ReaderIterator.handlePythonException(PythonRunner.scala:545)
        at org.apache.spark.api.python.PythonRunner$$anon$3.read(PythonRunner.scala:703)
        at org.apache.spark.api.python.PythonRunner$$anon$3.read(PythonRunner.scala:685)
        at org.apache.spark.api.python.BasePythonRunner$ReaderIterator.hasNext(PythonRunner.scala:498)
        at org.apache.spark.InterruptibleIterator.hasNext(InterruptibleIterator.scala:37)
        at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:491)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.agg_doAggregateWithoutKey_0$(Unknown Source)
        at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.processNext(Unknown Source)
        at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
        at org.apache.spark.sql.execution.WholeStageCodegenExec$$anon$1.hasNext(WholeStageCodegenExec.scala:759)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at org.apache.spark.shuffle.sort.BypassMergeSortShuffleWriter.write(BypassMergeSortShuffleWriter.java:140)
        at org.apache.spark.shuffle.ShuffleWriteProcessor.write(ShuffleWriteProcessor.scala:59)
        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:99)
        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:52)
        at org.apache.spark.scheduler.Task.run(Task.scala:131)
        at org.apache.spark.executor.Executor$TaskRunner.$anonfun$run$3(Executor.scala:506)
        at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1462)
        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:509)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
21/12/28 06:01:59 WARN TaskSetManager: Lost task 0.0 in stage 7.0 (TID 7) (kontroler executor driver): org.apache.spark.api.python.PythonException: Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/worker.py", line 619, in main
    process()
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/worker.py", line 611, in process
    serializer.dump_stream(out_iter, outfile)
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/serializers.py", line 259, in dump_stream
    vs = list(itertools.islice(iterator, batch))
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/util.py", line 74, in wrapper
    return f(*args, **kwargs)
  File "lab4.py", line 18, in <lambda>
    df = df.map(lambda x: (x[0].strip(','),x[1].strip(','),x[2].strip(','),x[3].strip(',')))
AttributeError: 'NoneType' object has no attribute 'strip'

        at org.apache.spark.api.python.BasePythonRunner$ReaderIterator.handlePythonException(PythonRunner.scala:545)
        at org.apache.spark.api.python.PythonRunner$$anon$3.read(PythonRunner.scala:703)
        at org.apache.spark.api.python.PythonRunner$$anon$3.read(PythonRunner.scala:685)
        at org.apache.spark.api.python.BasePythonRunner$ReaderIterator.hasNext(PythonRunner.scala:498)
        at org.apache.spark.InterruptibleIterator.hasNext(InterruptibleIterator.scala:37)
        at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:491)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.agg_doAggregateWithoutKey_0$(Unknown Source)
        at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.processNext(Unknown Source)
        at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
        at org.apache.spark.sql.execution.WholeStageCodegenExec$$anon$1.hasNext(WholeStageCodegenExec.scala:759)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at org.apache.spark.shuffle.sort.BypassMergeSortShuffleWriter.write(BypassMergeSortShuffleWriter.java:140)
        at org.apache.spark.shuffle.ShuffleWriteProcessor.write(ShuffleWriteProcessor.scala:59)
        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:99)
        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:52)
        at org.apache.spark.scheduler.Task.run(Task.scala:131)
        at org.apache.spark.executor.Executor$TaskRunner.$anonfun$run$3(Executor.scala:506)
        at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1462)
        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:509)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

21/12/28 06:01:59 ERROR TaskSetManager: Task 0 in stage 7.0 failed 1 times; aborting job
Traceback (most recent call last):
  File "lab4.py", line 48, in <module>
    spdf.select(F.avg(F.col("Emission")).alias("average")).show()
  File "/usr/local/lib/python3.6/site-packages/pyspark/sql/dataframe.py", line 494, in show
    print(self._jdf.showString(n, 20, vertical))
  File "/usr/local/lib/python3.6/site-packages/py4j/java_gateway.py", line 1310, in __call__
    answer, self.gateway_client, self.target_id, self.name)
  File "/usr/local/lib/python3.6/site-packages/pyspark/sql/utils.py", line 111, in deco
    return f(*a, **kw)
  File "/usr/local/lib/python3.6/site-packages/py4j/protocol.py", line 328, in get_return_value
    format(target_id, ".", name), value)
py4j.protocol.Py4JJavaError: An error occurred while calling o97.showString.
: org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 7.0 failed 1 times, most recent failure: Lost task 0.0 in stage 7.0 (TID 7) (kontroler executor driver): org.apache.spark.api.python.PythonException: Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/worker.py", line 619, in main
    process()
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/worker.py", line 611, in process
    serializer.dump_stream(out_iter, outfile)
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/serializers.py", line 259, in dump_stream
    vs = list(itertools.islice(iterator, batch))
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/util.py", line 74, in wrapper
    return f(*args, **kwargs)
  File "lab4.py", line 18, in <lambda>
    df = df.map(lambda x: (x[0].strip(','),x[1].strip(','),x[2].strip(','),x[3].strip(',')))
AttributeError: 'NoneType' object has no attribute 'strip'

        at org.apache.spark.api.python.BasePythonRunner$ReaderIterator.handlePythonException(PythonRunner.scala:545)
        at org.apache.spark.api.python.PythonRunner$$anon$3.read(PythonRunner.scala:703)
        at org.apache.spark.api.python.PythonRunner$$anon$3.read(PythonRunner.scala:685)
        at org.apache.spark.api.python.BasePythonRunner$ReaderIterator.hasNext(PythonRunner.scala:498)
        at org.apache.spark.InterruptibleIterator.hasNext(InterruptibleIterator.scala:37)
        at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:491)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.agg_doAggregateWithoutKey_0$(Unknown Source)
        at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.processNext(Unknown Source)
        at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
        at org.apache.spark.sql.execution.WholeStageCodegenExec$$anon$1.hasNext(WholeStageCodegenExec.scala:759)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at org.apache.spark.shuffle.sort.BypassMergeSortShuffleWriter.write(BypassMergeSortShuffleWriter.java:140)
        at org.apache.spark.shuffle.ShuffleWriteProcessor.write(ShuffleWriteProcessor.scala:59)
        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:99)
        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:52)
        at org.apache.spark.scheduler.Task.run(Task.scala:131)
        at org.apache.spark.executor.Executor$TaskRunner.$anonfun$run$3(Executor.scala:506)
        at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1462)
        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:509)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

Driver stacktrace:
        at org.apache.spark.scheduler.DAGScheduler.failJobAndIndependentStages(DAGScheduler.scala:2403)
        at org.apache.spark.scheduler.DAGScheduler.$anonfun$abortStage$2(DAGScheduler.scala:2352)
        at org.apache.spark.scheduler.DAGScheduler.$anonfun$abortStage$2$adapted(DAGScheduler.scala:2351)
        at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
        at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
        at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
        at org.apache.spark.scheduler.DAGScheduler.abortStage(DAGScheduler.scala:2351)
        at org.apache.spark.scheduler.DAGScheduler.$anonfun$handleTaskSetFailed$1(DAGScheduler.scala:1109)
        at org.apache.spark.scheduler.DAGScheduler.$anonfun$handleTaskSetFailed$1$adapted(DAGScheduler.scala:1109)
        at scala.Option.foreach(Option.scala:407)
        at org.apache.spark.scheduler.DAGScheduler.handleTaskSetFailed(DAGScheduler.scala:1109)
        at org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.doOnReceive(DAGScheduler.scala:2591)
        at org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:2533)
        at org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:2522)
        at org.apache.spark.util.EventLoop$$anon$1.run(EventLoop.scala:49)
Caused by: org.apache.spark.api.python.PythonException: Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/worker.py", line 619, in main
    process()
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/worker.py", line 611, in process
    serializer.dump_stream(out_iter, outfile)
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/serializers.py", line 259, in dump_stream
    vs = list(itertools.islice(iterator, batch))
  File "/usr/local/lib/python3.6/site-packages/pyspark/python/lib/pyspark.zip/pyspark/util.py", line 74, in wrapper
    return f(*args, **kwargs)
  File "lab4.py", line 18, in <lambda>
    df = df.map(lambda x: (x[0].strip(','),x[1].strip(','),x[2].strip(','),x[3].strip(',')))
AttributeError: 'NoneType' object has no attribute 'strip'

        at org.apache.spark.api.python.BasePythonRunner$ReaderIterator.handlePythonException(PythonRunner.scala:545)
        at org.apache.spark.api.python.PythonRunner$$anon$3.read(PythonRunner.scala:703)
        at org.apache.spark.api.python.PythonRunner$$anon$3.read(PythonRunner.scala:685)
        at org.apache.spark.api.python.BasePythonRunner$ReaderIterator.hasNext(PythonRunner.scala:498)
        at org.apache.spark.InterruptibleIterator.hasNext(InterruptibleIterator.scala:37)
        at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:491)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.agg_doAggregateWithoutKey_0$(Unknown Source)
        at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.processNext(Unknown Source)
        at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
        at org.apache.spark.sql.execution.WholeStageCodegenExec$$anon$1.hasNext(WholeStageCodegenExec.scala:759)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
        at org.apache.spark.shuffle.sort.BypassMergeSortShuffleWriter.write(BypassMergeSortShuffleWriter.java:140)
        at org.apache.spark.shuffle.ShuffleWriteProcessor.write(ShuffleWriteProcessor.scala:59)
        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:99)
        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:52)
        at org.apache.spark.scheduler.Task.run(Task.scala:131)
        at org.apache.spark.executor.Executor$TaskRunner.$anonfun$run$3(Executor.scala:506)
        at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1462)
        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:509)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
ledi12
  • Rejestracja:prawie 6 lat
  • Ostatnio:2 miesiące
  • Lokalizacja:Wrocław
1
Kopiuj
'NoneType' object has no attribute 'strip'

Mówi jasno, że próbujesz zastosować metodę stringową na obiekcie, który nie jest stringiem. Jak na moje to wartości w twoim df są nullami.

Co do mojego przykładu na średnią to działa na 100% -> przetestowałem zanim tutaj wrzuciłem.


Robię http response status cody w martwych ciągach
FB
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 2 lata
  • Postów:25
0
ledi12 napisał(a):
Kopiuj
> 'NoneType' object has no attribute 'strip'
> ```
> Mówi jasno, że próbujesz zastosować metodę stringową na obiekcie, który nie jest stringiem. Jak na moje to wartości w twoim df są nullami.
> 
> Co do mojego przykładu na średnią to działa na 100% -> przetestowałem zanim tutaj wrzuciłem.

Nie jest stringiem, no chyba, ze to sie inaczej srpawdza? 

![screenshot-20211229193026.png](https://4programmers.net/uploads/109704/f2FIiYE8YY3gSS4Eda5PSr4jqn2ioZSs8Hr7cm5Q.png)


@edit

Wykonuje tylko ten Twój kod: 

```python
eventsDF.select(F.avg(F.col("Emission")).alias("average"))

i przy nim ten error wyrzuca, znaczy dopusuje tam jeszcze

Kopiuj
.show()

, bo bez show jest tylko:

screenshot-20211229193416.png

edytowany 4x, ostatnio: fajny_bolek
ledi12
  • Rejestracja:prawie 6 lat
  • Ostatnio:2 miesiące
  • Lokalizacja:Wrocław
1

No printschema mówi jasno, że dozwolone są nulle w wartościach stąd do map możesz dodać warunek

Kopiuj
if type(x) is str

Nie wiem jakie masz wytyczne odnośnie ogólnej transformacji, ale zawsze możesz wyczyścic df z nulli tworząc nowy

Kopiuj
twojnowydf = df.na.drop(how='any')

how='any' usuwa wszystkie row, które zawierają chociaż jednego nulla.

do poczytania: https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.DataFrame.dropna.html


Robię http response status cody w martwych ciągach
edytowany 1x, ostatnio: ledi12
Zobacz pozostałe 4 komentarze
FB
oo zadziałało :)
FB
tylko jak do tego teraz dodać jeszcze kraj? Próbowałem w select wrzucic spdf.country, ale to nie zadziałało
ledi12
W sensie per kraj? Użyj funkcji agregującej od @Spine
FB
tak, udało się :)
FB
Próbuję teraz zrobić max z avg, ale tez mi nie idzie. Zrobiłem tak: spdf.select(spdf.Country, spdf.Emission).groupBy(spdf.Country).avg('Emission').max().show(), ale to nie dziala
ledi12
  • Rejestracja:prawie 6 lat
  • Ostatnio:2 miesiące
  • Lokalizacja:Wrocław
1

@fajny_bolek:

Kopiuj
df2 = (df.select(col("*"))
       .groupBy("Country")
       .agg(
         avg("Emission")
         .alias("average"))
      .sort(col("average").desc()))
df2.show(1)

Wypluje Ci row z maxem

a jak chcesz samą wartość

Kopiuj
maksymalna_wartosc = df2.select(max("average")).take()

Robię http response status cody w martwych ciągach
edytowany 4x, ostatnio: ledi12
Zobacz pozostałe 3 komentarze
FB
hmm a funkcje col muszę skądś zaimportować?
ledi12
from pyspark.sql.functions import *
FB
ok, dzięki. Pytanie tylko czy to na pewno jest tylko DataFrame API ?
ledi12
No tak. Użyj metody type() jak nie wierzysz. Cały czas pracujesz na dataframe.
ledi12
Kwerendy czysto sql'owe to inna bajka. Musisz zainicjalizować spark context, stworzyć temp view table ze swojego df itp. To dwie różne rzeczy.
FB
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 2 lata
  • Postów:25
0

W jakiej lokalizacji na Cent OS znajdę plik spark-defaults.conf?? Bo nie mogę go nigdzie zainstalować. Jak instalowałem to zrobiłem tylko

Kopiuj
pip install pyspark

I wszystko mi działa, ale nie mogę tego pliku konfiguracyjnego nigdzie znaleźć. :(

edytowany 1x, ostatnio: fajny_bolek

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.