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 ---
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 ---
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 ]
a webservice-t nem én írom, én majd csak kommunikálok vele.
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?
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 ]
É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...
Levágja 1024-nél és új üzenet lesz. De nem jöhet több gyakorlatilag sem.
sose becsüld le a felhasználókat (és mindig validáld az inputokat)
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...
é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!
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 ]
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?
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?
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.
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.
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.
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().
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...
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.
Igen, viszont nem kapok socket error-t valamiért.
Akkor sem, ha a kliens lezárja rendesen a socketet, amikor kilép?
Ú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?
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
Köszi, egy így szuperül működik.
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.
newArr = list(set(arr))
Same rules apply!
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)
Köszi, szuper, így már értem, hogy hol hibáztam. Azt hittem, hogy a list comprehension a "map-elésnek" felel meg. (neked is kösz EQMontoya)
[ Szerkesztve ]
+1, nagyon frappáns!
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.
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!
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?
classmethod lesz az, kösz! Pedig már láttam egyszer említve valahol, de nem jutott eszembe.
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.
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"
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.
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"
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.
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?
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!
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}
Hat igen, igy viszont az O(1) kereses helyett kapsz egy linearisat, ami eleg painful.
Same rules apply!
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.
Ez nagyon tetszik, köszönöm! Neked mindig olyan szép megoldásaid vannak!
(#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!
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.
A key comparison operatoratol fugg, mert hash egyezes eseten meg kell vizsgalni, hogy tenyleg egyforma-e a ket elem.
Same rules apply!
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.