Hirdetés

2024. április 25., csütörtök

Gyorskeresés

Hozzászólások

(#2001) justmemory válasza Siriusb (#1998) üzenetére


justmemory
senior tag

Szia,

én ezt találtam a témában - C-ben elvileg van rá megoldás, de pythonból az sajnos kimaradt...

--- Imprisoned, inside this mind... --- Joined at the soul with a pair of headphones ---

(#2002) n00n


n00n
őstag

Sziasztok!

Ismerkedek a Pythonnal még csak, de írtam egy egyszerű TCP szervert/klienset. Ránéznétek és elmondanátok, hogy mi a véleményetek róla? Mit csinálnátok másképp? A cél az volt, hogy a szerver folyamatosan figyel a 9999-es porton, a kliens csatlakozik hozzá és onnantól kezdve folyamatos beszélgetés megy, szóval nincs a socket lezárva. Két fajta üzenet jöhet a klienstől:

id|name|message\n
id|name|HEARTBEAT\n

pl.:

001|client|test_message\n
001|client|HEARTBEAT\n

Ha az első akkor meghív egy localhostos php szervert a python server, ami visszaad egy választ, egyelőre mindig ugyanazt adja vissza, később a message alapján más lesz.

pl:

001|server|test_response\n

vagy ha HEARTBEAT jön, akkor a server visszaválaszol az id-val:

001|server|HEARTBEAT\n

remélem érthető :)

Kódok:

server.py:
https://pastebin.com/nBB578TV

client.py:
https://pastebin.com/m52wjz7R

[ Szerkesztve ]

(#2004) n00n válasza s1999xx (#2003) üzenetére


n00n
őstag

a webservice-t nem én írom, én majd csak kommunikálok vele. :)

(#2005) kovisoft válasza n00n (#2002) üzenetére


kovisoft
őstag

A conn.recv(1024) blokkol, amíg nem kapta meg mind az 1024 byte-ot, nem? Működik ez így neked, ha csak egyetlen rövid üzenet jön a klienstől?

(#2006) n00n válasza kovisoft (#2005) üzenetére


n00n
őstag

Utánaolvastam és nem vár 1024 byte-ra. A send() elküldi a küldött byte-ok számát is, így a recv azt is megkapja. Szóval ha kevesebb az nem baj,, de 1024 lehet maximum nálam. Aminél több nem is jöhet nálam.

socket.recv(bufsize[, flags])
Receive data from the socket. The return value is a bytes object representing the data received. The maximum amount of data to be received at once is specified by bufsize.

Egyébként működik:

Server:
test@test-machine:~/pyproject python3 server.py
2019-02-27 13:38:47,062 - 192.168.0.2:39620 - Connected
2019-02-27 13:38:52,597 - 192.168.0.2:39620 - Message received: b'Hi\n'
2019-02-27 13:38:53,603 - 192.168.0.2:39620 - Message sent: b'Welcome\n'

Client:
test@test-machine:~/pyproject python3 client.py
Hi
Response: b'Welcome\n'

[ Szerkesztve ]

(#2007) sztanozs válasza n00n (#2006) üzenetére


sztanozs
veterán

És mi történik akkor, ha mégis többet küld, mint 1024 byte?

JOGI NYILATKOZAT: A bejegyzéseim és hozzászólásaim a személyes véleményemet tükrözik; ezek nem tekinthetők a munkáltatóm hivatalos állásfoglalásának...

(#2008) n00n válasza sztanozs (#2007) üzenetére


n00n
őstag

Levágja 1024-nél és új üzenet lesz. De nem jöhet több gyakorlatilag sem.

(#2009) sztanozs válasza n00n (#2008) üzenetére


sztanozs
veterán

sose becsüld le a felhasználókat (és mindig validáld az inputokat) :DDD

JOGI NYILATKOZAT: A bejegyzéseim és hozzászólásaim a személyes véleményemet tükrözik; ezek nem tekinthetők a munkáltatóm hivatalos állásfoglalásának...

(#2010) Siriusb válasza sztanozs (#1999) üzenetére


Siriusb
veterán

és cain69, justmemory,
Köszönöm a válaszokat!
Tudom, hogy az sqlite meglehetősen behatárolt az eltérő működésű adatbázisokhoz képest, s bizonyos feladatokra optimálisabb mást választani, sőt ez nem is lehet alternatíva. Próbálom kitapasztalni, meddig lehet benne elmenni, nem volt vele eddig tapasztalatom.
Bújtam a netet, olvasgattam a leírásokat, de igazán jó megoldást nem találtam, ezért dobtam be ide a kérdést, hátha... Marad, hogy nem az adatbázis felől kezelem le a dolgot.

Nagyon köszönöm, hogy mindig kifejtitek a véleményeteket, nem egy-két szóval intézitek el a választ! :R

(#2011) n00n


n00n
őstag

Egyébként a recv-n kívül láttok még valamit a kódban, amit egyáltalán nem így kellene megvalósítani vagy lehetne jobban is, stb?

[ Szerkesztve ]

(#2012) kovisoft válasza n00n (#2011) üzenetére


kovisoft
őstag

Nekem a thread kezelés nem teljesen kerek. Ha jól látom, minden egyes kliens csatlakozásánál létrejön egy szerver thread, ami végtelen ciklusban fut, és akkor sem lép ki, amikor a kliens lezárta a kapcsolatot (minden exception le van nyelve a ciklusban). Tehát ha sokszor csatlakoznak a kliensek, akkor ezek a thread-ek mind megmaradnak. Vagy rosszul látom?

(#2013) n00n válasza kovisoft (#2012) üzenetére


n00n
őstag

Alap esetben az az elképzelés, hogy nincs lezárva a kapcsolat soha, de jogos, amit mondasz, mert hiba miatt ilyenkor valóban megmarad a thread. Hol kellene elkapnom?

(#2014) kovisoft válasza n00n (#2013) üzenetére


kovisoft
őstag

Szerintem ha a recv dob egy socket.error-t, akkor ki lehet lépni a végtelen ciklusból, és befejezni a thread futását.

(#2015) kovisoft válasza n00n (#2011) üzenetére


kovisoft
őstag

Másik megjegyzésem a kliensre vonatkozik: a kliens egy cikluson belül olvassa a szervertől jövő választ, ill. küldi az új üzenetet. Viszont ha a szerver valamiért sokáig nem válaszol, akkor a recv blokkol, és ezért addig új üzenetet sem fog tudni küldeni. Ez nem feltétlen baj, hogy nincsenek egymásra eresztve az üzenetek, de innen hiányzik nekem minimum valami hibakezelés. Pl. mi történjen socket.error esetén? Lépjen ki a kliens? Vagy próbáljon nyitni egy új kapcsolatot a szerver felé? Ki kell-e timeout-olni, ha valamiért nem érkezik meg a válasz egy üzenetre? Heartbeat küldést most nem látok, de ha lenne, akkor gondolom fontos lenne, hogy egy beragadt üzenet ne blokkolja a heartbeat-et.

(#2016) n00n válasza kovisoft (#2014) üzenetére


n00n
őstag

beraktam egy ilyet:

except Exception as e:
logging.error("Error receiving data: " + e)

De valamiét ha megszakítom a klienst ctrl+c-vel, az nem küld semmilyen exception-t, próbáltam Exception helyet socket.error-ral is.

Kliens: az csak tesztelési célzattal készült, a szerveren lenne a fő hangsúly. :)

(#2017) kovisoft válasza n00n (#2016) üzenetére


kovisoft
őstag

Esetleg azt tudod csinálni, hogy a kliensben kezeled azt, hogy bármilyen okból kilép a kliens, mindenképpen zárja le a socketet. Pl. az egész mehetne egy try blokkba, aminek a finally ágában van a server.close().

(#2018) sztanozs válasza n00n (#2016) üzenetére


sztanozs
veterán

Sima Exception helyett ezzel próbáld meg:
except (KeyboardInterrupt, SystemExit):

[ Szerkesztve ]

JOGI NYILATKOZAT: A bejegyzéseim és hozzászólásaim a személyes véleményemet tükrözik; ezek nem tekinthetők a munkáltatóm hivatalos állásfoglalásának...

(#2019) kovisoft válasza sztanozs (#2018) üzenetére


kovisoft
őstag

Két exception-ről van most szó. Az egyiket a szerverben szeretné elkapni, a KeyboardInterrupt viszont a kliensben jön be. Amit írsz tehát, annak a kliensbe kellene mennie, a szerverben akár elég lenne a socket.error-t elkapni.

(#2020) n00n válasza kovisoft (#2019) üzenetére


n00n
őstag

Igen, viszont nem kapok socket error-t valamiért.

(#2021) kovisoft válasza n00n (#2020) üzenetére


kovisoft
őstag

Akkor sem, ha a kliens lezárja rendesen a socketet, amikor kilép?

(#2022) n00n válasza kovisoft (#2021) üzenetére


n00n
őstag

Úgy sem kapok exception-t, viszont a socketet lezárja, viszont ami baj, hogy benne marad abban a threadben a server. Hogy tudnám azt a threadet is lezárni?

(#2023) kovisoft válasza n00n (#2022) üzenetére


kovisoft
őstag

Most nem tudom kipróbálni, de arra tudok még gondolni, hogy esetleg a recv üres stringet vagy None-t ad vissza ilyenkor. Mi történik, ha beleteszel egy ilyen else ágat?

message = conn.recv(1024)
if message:
...
else:
break

(#2024) n00n válasza kovisoft (#2023) üzenetére


n00n
őstag

Köszi, egy így szuperül működik. :R

(#2025) Lacc


Lacc
aktív tag

Hali, ezt hogyan lehet átalakitani egysorosá?

A lényeg, hogy ne másolja át a duplikált elemeket a másik tömbbe
Ez műkődik

newArr = []
for i in arr:
if i not in newArr:
newArr.append(i)

De ez már nem, ez az "egysoros" változat, bocsánat nem tudom a nevét.

newArr = []
newArr = [i for i in arr if i not in newArr]

Ugyanis ez a változat ugyanúgy beleteszi a duplikált elemeket is.

(#2026) EQMontoya válasza Lacc (#2025) üzenetére


EQMontoya
veterán

newArr = list(set(arr))

Same rules apply!

(#2027) kovisoft válasza Lacc (#2025) üzenetére


kovisoft
őstag

EQMontoya megoldása talán a legegyszerűbb, legelegánsabb és leggyorsabb, viszont nem tartja meg az eredeti elemek sorrendjét. Nem tudom, hogy ez szempont volt-e, mindenesetre ha igen, és list comprehensiont akarsz használni, akkor itt egy olyan verzió, ami megtartja az elemek sorrendjét:

newArr = []
[newArr.append(i) for i in arr if i not in newArr]
print(newArr)

(#2028) Lacc válasza kovisoft (#2027) üzenetére


Lacc
aktív tag

Köszi, szuper, így már értem, hogy hol hibáztam. Azt hittem, hogy a list comprehension a "map-elésnek" felel meg. :R (neked is kösz EQMontoya)

[ Szerkesztve ]

(#2029) velizare válasza EQMontoya (#2026) üzenetére


velizare
nagyúr

+1, nagyon frappáns! :D

Tudod, mit jelent az, hogy nemezis? Az érintett, erősebb fél kinyilatkoztatása a méltó büntetés mértékét illetően. Az érintett fél jelen esetben egy szadista állat... én.

(#2030) Janos46


Janos46
tag

Sziasztok!
Kezdő vagyok. Hogyan kell megírni, hogy ne egymás alá, hanem egymás mellé sorba írja ki az eredményt?
Gondolom egyszerű dolog (de nem nekem).Köszi a segítséget.
def sorba10():
a=1
while a<11:
print (a*5)
a=a+1
sorba10()

Artillery, lelkes újonc vagyok, tanulni akarok!

(#2032) Siriusb


Siriusb
veterán

Adott 3 osztály:
ClassA()
    def f1()
ClassB(ClassA)
    def f1()
ClassC(ClassB, ClassA)
    def f1()

Szeretém ClassC-ben végrehajtatni a ClassB.f1()-et anélkül, hogy bármi mást örökölne ClassB-ből vagy ClassB-nek testet kéne öltenie, illetve C.f1()-re bármiféle hatása lenne. Lehetséges ez?

(#2034) Siriusb válasza s1999xx (#2033) üzenetére


Siriusb
veterán

classmethod lesz az, kösz! Pedig már láttam egyszer említve valahol, de nem jutott eszembe.

(#2035) Siriusb


Siriusb
veterán

Gtk kérdés, linux+primary selection(középső egérgombbal másolás):

Label, entry esetén működik, hogy az itt kijelölt szöveget középső gomb nyomásával beillesszem más alkalmazásba, viszont CellRendererText (editable=true) használatakor nem.

Mi ennek az oka, és mi a gyógyír rája? A barátom és én nem tudtunk megoldást találni.

(#2036) cousin333 válasza Siriusb (#2032) üzenetére


cousin333
addikt

Először is: a ClassC feleslegesen örököl a ClassA-tól, hiszen a ClassB már megörökölt tőle mindent.

"Szeretném ClassC-ben végrehajtatni a ClassB.f1()-et anélkül, hogy bármi mást örökölne ClassB-ből"

Erről már lekéstél, tekintve, hogy a ClassC a ClassB-ből örököl... :)

Feltételezve, hogy a ClassC-t úgyis példányosítod, a super() lesz a megoldás

class A:
def f1(self):
print('f1 in Class A')

class B(A):
def f1(self):
print('f1 in Class B')

class C(B):
def f1(self):
print('f1 in Class C')

def f2(self):
super().f1()

c = C()
c.f2()

f1 in Class B

Ha pedig konkrétan a ClassA f1() függvényét akarod elérni, akkor:

class A:
def f1(self):
print('f1 in Class A')

class B(A):
def f1(self):
print('f1 in Class B')

class C(B):
def f1(self):
print('f1 in Class C')

def f2(self):
super(B, self).f1()

c = C()
c.f2()

f1 in Class A

A classmethod is mehet, de akkor nem kell a ClassC-nek a ClassB-ből örökölnie.

[ Szerkesztve ]

"We spared no expense"

(#2037) Siriusb válasza cousin333 (#2036) üzenetére


Siriusb
veterán

Nem örököl feleslegesen, mert mindegyik alosztályt a ClassA-ból származtatom le. Pl. nem szeretném megörökölni ClassB.f1()-t, mert az eredetire van szükségem ClassC-ben, nem az itt felülírottra. Valamint emellett bizonyos körülmények esetén szükséges meghívni a ClassB.f1()-t ClassC-ből.
ClassC-nél csak azért írtam be a felmenők közé ClassB-t is, mert érzékelteteni szerettem volna, hogy annak egyik metódusára is szükségem van.

(#2038) cousin333 válasza Siriusb (#2037) üzenetére


cousin333
addikt

De azzal kezdted a mondandódat, hogy "Adott 3 osztály:", majd felsoroltad őket örökléssel együtt. Vagy örököl, vagy nem, de ezzel ne "érzékeltess" semmit, mert az félrevezető... :)

Ebben az esetben valóban a classmethod tűnik jó megoldásnak (esetleg a staticmethod), mindazonáltal az örökléssel is megoldható, hogy akár a saját f1() függvényt, akár a szülő osztályok f1() függvényét használd tetszés szerint.

A fenti példa így az alábbiak szerint módosulhat:

class A:
def f1(self):
print('f1 in Class A')

class B(A):

@classmethod
def f1(cls):
print('f1 in Class B')

class C(A):
def f1(self):
print('f1 in Class C')

def f2(self):
B.f1()

c = C()
c.f2()

f1 in Class B

[ Szerkesztve ]

"We spared no expense"

(#2039) Siriusb válasza cousin333 (#2038) üzenetére


Siriusb
veterán

Eredetileg így írtam le: ClassC(ClassB, ClassA), csak valahogy az áthúzás eltűnt, én meg nem vettem észre. :(
Szóval így valóban félrevezető lett, elnézést.

(#2040) Siriusb


Siriusb
veterán

Ismét egy fejtörő:
Egy dict-ben tudom egyszerűen vizsgálni, hogy van-e benne olyan key, ami pl. tuple típusú? Vagy csak ciklusban tudom megnézni?

(#2042) EQMontoya válasza Siriusb (#2040) üzenetére


EQMontoya
veterán

Hat a dict.keys visszaad egy listat, amit tudsz filterezni.

Tehat pl. igy:
tuple_keys = list(filter(lambda x: isinstance(x, tuple), d.keys()))

Fejbol irtam, nem probaltam ki, lehet benne typo. :)

[ Szerkesztve ]

Same rules apply!

(#2043) kovisoft válasza EQMontoya (#2042) üzenetére


kovisoft
őstag

De hát ugye ez is egy ciklus, hiszen végigmegy a filter a kulcsokon. :)

Ha nagyon fontos, hogy O(1) lépésben meglegyen, akkor típus szerint külön dict-ben célszerű tárolni az elemeket. Ekkor viszont az összes dict-ben egyszerre történő keresés lesz macerásabb, amire lehet írni egy függvényt, ami típus szerint a megfelelő dict-ből olvas. Vagy lehet használni az unpacking operatort (**) a dict-ek összefűzésére, pl:

> dtuple={(1,2,3):1, (4,5,6):2}
> dint={7:3, 8:4}
> {**dtuple, **dint}
{(1, 2, 3): 1, (4, 5, 6): 2, 7: 3, 8: 4}

(#2044) EQMontoya válasza kovisoft (#2043) üzenetére


EQMontoya
veterán

Hat igen, igy viszont az O(1) kereses helyett kapsz egy linearisat, ami eleg painful.

Same rules apply!

(#2045) kovisoft válasza EQMontoya (#2044) üzenetére


kovisoft
őstag

Igen, O(1) akkor lesz, ha írunk egy függvényt arra, hogy típus szerinti dict-ből olvasson. Hagyjuk is a dict-ek összefűzését, mert az performanciában tényleg rossz.

(#2046) Siriusb válasza EQMontoya (#2042) üzenetére


Siriusb
veterán

Ez nagyon tetszik, köszönöm! Neked mindig olyan szép megoldásaid vannak! :R

(#2043) kovisoft
Habár igazad vagyon, nekem mégis jólesik ránézni a megoldására. :)
Ráadásul még tanultam is valami újat.
Kösz a Te megoldásod is! :R

(#2047) axioma válasza kovisoft (#2045) üzenetére


axioma
veterán

Errol nekem az a kerdes jut eszembe, meddig tekintheto O(1)-nek, mert azert egy bizonyos elemszam utan mar nem feltetlen. Sot bonyolultabb key eseten mire a key-n vegigmegy az se feltetlen konstans.

(#2048) EQMontoya válasza axioma (#2047) üzenetére


EQMontoya
veterán

A key comparison operatoratol fugg, mert hash egyezes eseten meg kell vizsgalni, hogy tenyleg egyforma-e a ket elem.

Same rules apply!

(#2049) axioma válasza EQMontoya (#2048) üzenetére


axioma
veterán

Hat addig OK, ha egy egyezest kell vizsgalni. De mi van ha tobb hash egybeesik es meg kell keresni kozule hogy melyik a mienk, ott mar minimum valami logaritmikus tag bejon. En inkabb erre gondoltam. Ill. pl. ha stringrol beszelunk, akkor linearis a hosszaval az egyezes-vizsgalat.
De ez azert az itt felmerulo peldaknal nyilvan irrelevans.

(#2050) kovisoft válasza axioma (#2047) üzenetére


kovisoft
őstag

Márpedig ez O(1), mert az eredeti probléma szerint nem key lookupról van szó, hanem pusztán annyit kell vizsgálni, hogy a tuple típushoz használt dict üres-e.

Copyright © 2000-2024 PROHARDVER Informatikai Kft.