- WLAN, WiFi, vezeték nélküli hálózat
- Vodafone otthoni szolgáltatások (TV, internet, telefon)
- Programozás topic
- Milyen routert?
- Kodi és kiegészítői magyar nyelvű online tartalmakhoz (Linux, Windows)
- Asustor NAS
- DIGI internet
- Túlmelegednek az NVIDIA új AI-chipjei
- 300 milliárd dollárt érhet a TikTok anyacége
- ArchiCAD és Artlantis topik
Új hozzászólás Aktív témák
-
válasz #79484416 #4201 üzenetére
Igen, HW-esen rásegít az SHA kiszámolására.
Freeware, és akciós programok egy helyen https://www.facebook.com/freewarenews
-
don_peter
senior tag
Sziasztok. Nem vagyok python-os, de sajna muszáj vele foglalkoznom. Egy feladat megoldásával kínlódok, de nem jövök rá a megoldásra. Segítségeteket kérem. Köszi előre is.
Probléma:
Van egy adathalmazom, amely byte-os sorozat és ezt szeretném struktúrába rendezni:record = b'\x08\x32\x12\x33\x10\xEE\x0a\xff\x01\xAA\x22\x55\x99\x0f\x02\x06\x66\x76'
print('\n\r',len(record))
s= namedtuple('struct',
'header' # Uint8 [6]
'id' # Uint32
'time' # Uint64
)
s = s._make(unpack('6bHq', record))
A lényeg, hogy az egyes elemekbe a megfelelő számú byte kerüljön. Ha meg lehet oldani tömbösítve az is érdekes lehet, de nem szükséges. Köszi.[ Szerkesztve ]
----== Neo Geo és Arcade Fórum : www.neo-geo.hu ==----
-
sztanozs
veterán
válasz don_peter #4203 üzenetére
Kerdes lehet meg, hogy BE, vagy LE a byte rendezes...
Tudod, hogy milyen ertekeket kell felvegyen a rekord alapjan a struct?namedtuple megy egyebkent igy is:
s = namedtuple('struct',('header','id','time'))
vagy vesszovel elvalasztva:s = namedtuple('struct', 'header,id,time')
[ 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...
-
sztanozs
veterán
válasz #79484416 #4205 üzenetére
BE vs LE:
>>> s._make(unpack('>6sIQ', record))
struct(header=b'\x082\x123\x10\xee', id=184484266, time=2474051860047488630)
>>> s._make(unpack('<6sIQ', record))
struct(header=b'\x082\x123\x10\xee', id=2852257546, time=8531513150021391650)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...
-
-
creative123
friss újonc
Sziasztok,
Most ismerkednék a python-nal, és lenne egy olyan kérdésem amire nem találtam még sehol leírást. Minden oktatóvideóban szépen sorba vesznek mindent, adatok, függvények..stb. Majd egyszercsak megírnak belőle egy programot Import kezdetű bevezetéssel.
De erről én nem találtam semmit, hogy hogyan, honnan tudod, mikor mit kell használni?
Igen tudom, hogy a programokban használatos dolgokhoz szükséges, de erről nem találok sehol infót, hogy mégis mi alapján tudod, hogy mihez mi kell?
Köszi a választ előre is. -
Atomantiii
addikt
Újabb xml fájlos kérdésem lenne, hátha valakinek lenne ötlete hogyan induljak el.
Ilyen tartalom van az xml fájomban, hogy pl:
<programme start="20240226052500 +0100" channel="5.port.hu" stop="20240226060000 +0100" clumpidx="0/1">
<title>Fókusz</title>
<sub-title lang="hu">(magazinműsor, 2024)</sub-title>
<desc lang="hu">Hétköznaponként jelentkező riportmagazin a legfrissebb hírekkel, aktuális információkkal, eseményekkel, emberi sorsokkal, érdekes történetekkel és helyszínekkel a világ minden részéről az RTL Gold-on is. Az RTL Klub mai adása felvételről.</desc>
<date>2024</date>
<category lang="en">Magazines/Reports/Documentary</category>
<category lang="hu">Magazinok/Riportok/Dokumentumfilm</category>
<category lang="en">tvshow</category>
<url system="port.hu">https://port.hu/adatlap/film/tv/fokusz/event-tv-1416159575-5/movie-3806</url>
<previously-shown/>
<rating>
<value>12</value>
<icon src="https://port.hu/img/agelimit/raster/12_age_icon_black.png"/>
</rating>
</programme>Hogy tudnék egy olyan xml-t csinálni belőle, amivel törölném a felesleges sorokat belőle?
Pl ne legyenek benne ezek a sorok:
<url system="port.hu">https://port.hu/adatlap/film/tv/fokusz/event-tv-1416159575-5/movie-3806</url>
<value>12</value>
<icon src="https://port.hu/img/agelimit/raster/12_age_icon_black.png"/>
<category lang="en">Magazines/Reports/Documentary</category>Valakinek ötlete akár arra is, hogy neten hol keresgéljek?
-
Hege1234
addikt
válasz Atomantiii #4215 üzenetére
ezt nem probléma megcsinálni ezzel a modullal:
xml.etree.ElementTree
azthiszem alapból benne van a python 3-baa példád csak egy programra mutat
hogyan néz ki amikor van pl. 2 vagy 3 benne? -
Atomantiii
addikt
válasz Hege1234 #4217 üzenetére
Ez a teljes fájl. Ebből szeretnék kitakarítani felesleges dolgokat.
Pl az url-eket, ikonokat esetleg még másokat is, de ha már az egyik összejönne az is sokat jelentene méretben, mert több ezer van benne.
<url system="port.hu">http://port.hu/adatlap/szemely/peter-breitmayer/person-293341</url>
<icon src="https://port.hu/img/agelimit/raster/12_age_icon_black.png" />[ Szerkesztve ]
-
Hege1234
addikt
válasz Atomantiii #4218 üzenetére
valami ilyesmi (biztos van jobb megoldás is rá)
(sokkal amúgy nem lett kisebb a fájl..)import requests
import xml.etree.ElementTree as ET
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
}
xml_content = requests.get('ide írd a linket', headers=headers).content
root = ET.fromstring(xml_content)
not_needed = ["url", "previously-shown", "rating"]
for programme in root.findall(".//programme"):
for element_name in not_needed:
elements = programme.findall(f".//{element_name}")
for element in elements:
if element in programme:
programme.remove(element)
edited_tv_programs = ET.tostring(root, encoding='unicode')
with open('edited_tv_programs.xml', 'w', encoding='utf-8') as file:
file.write(edited_tv_programs)[ Szerkesztve ]
-
Hege1234
addikt
válasz Atomantiii #4220 üzenetére
esetleg fontold meg a "credits" kiszedését is
akkor úgy kb. 40 MB lesz összesennot_needed = ["url", "previously-shown", "rating", "credits"]
-
Atomantiii
addikt
válasz Hege1234 #4221 üzenetére
Abban tudnál még segíteni, hogy ezt hogy tudom átírni, hogy ne a tárhelyről, hanem a saját gépemről töltse be a forrás xml-t és oda is mentse le?
Próbáltam, de nem igazán akar összejönni, mindig hibát ír erre a sorra:
edited_tv_programs = ET.tostring(root, encoding='unicode')
Traceback (most recent call last):
File "d:\EPG\xmlremove.py", line 24, in <module>
edited_tv_programs = ET.tostring(root, encoding='unicode')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Python312\Lib\xml\etree\ElementTree.py", line 1083, in tostring
ElementTree(element).write(stream, encoding,
File "C:\Python312\Lib\xml\etree\ElementTree.py", line 728, in write
serialize(write, self._root, qnames, namespaces,
File "C:\Python312\Lib\xml\etree\ElementTree.py", line 851, in _serialize_xml
tag = elem.tag
^^^^^^^^
AttributeError: 'ElementTree' object has no attribute 'tag'[ Szerkesztve ]
-
Atomantiii
addikt
-
Atomantiii
addikt
Ez így nagyon szuper, de esetleg lehetne neki mondani valahogy egy olyat, hogy törölje még ezt ki az xml-ből? " clumpidx="0/1" és helyette csak egy ilyet rakjon be: "
Notepad++-ban egy sima keresés és cserével megoldható, de jó lett volna valahogy automatizálni.
-
Hege1234
addikt
válasz Atomantiii #4225 üzenetére
az elejére akkor ezt add még hozzá:
import re
edited_tv_programs = ... alatt pedig ez legyen:
edited_tv_programs = re.sub(r'( clumpidx=.*\")', r'', edited_tv_programs)
[ Szerkesztve ]
-
Atomantiii
addikt
válasz Hege1234 #4226 üzenetére
Közben találtam még egy olyat, hogy egyes sorokban van feleslegben egy ilyen a <desc lang="hu"> után, hogy zárójel nulla pont zárójel szóköz, ami felesleges. Ezt próbáltam kitörölni, de sehogy sem sikerül.
<desc lang="hu">(0.) Get ready as we bring you all of the greatest hits from singing sensation Ariana Grande!</desc>
edited_tv_programs = re.sub(r'<desc lang="hu">(0.) ', r'<desc lang="hu">', edited_tv_programs)
Akárhogy csináltam mindig csak a kezdő zárójel tűnt el de a 0 és a többi maradt.
[ Szerkesztve ]
-
Hege1234
addikt
válasz Atomantiii #4228 üzenetére
sztem az valahogy így nézne ki:
edited_tv_programs = re.sub(r'<desc.*hu.*(\(.*\.\) )', r'<desc lang="hu">', edited_tv_programs)
ha csak tényleg a (0.) ami nem kell akkor így
edited_tv_programs = re.sub(r'<desc.*hu.*(\(0.\) )', r'<desc lang="hu">', edited_tv_programs)
[ Szerkesztve ]
-
Atomantiii
addikt
válasz Hege1234 #4229 üzenetére
Köszi, jó lett.
edited_tv_programs = re.sub(r'<desc lang="hu">(\(.*\.\) )', r'<desc lang="hu">', edited_tv_programs)
Elvileg elég lenne a desc lang hu-s rész nélkül is, de így is jó. Már itt kínlódtam vele egy jó ideje, sehol sem találtam meg, hogy hivatkozzak a zárójelre, a 0-ra és a .-ra egyszerre.
Így az eredeti 85 MB-os fájlból lett 33 MB.
[ Szerkesztve ]
-
sztanozs
veterán
válasz Atomantiii #4215 üzenetére
Szerintem mashogyan kellene megkozeliteni... vsz csak azt kellene kivalogatni, ami neked kell.
Fel tudod rakni valahova mashova a fajlt? Melohelyrol nem erem el...[ 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...
-
Atomantiii
addikt
válasz sztanozs #4231 üzenetére
Működik Hege javaslata is, persze biztos meg lehet csinálni máshogy is. Itt a forrás fájl.
import xml.etree.ElementTree as ET
import re
xml_content = ET.parse('forras.xml')
root = xml_content.getroot()
not_needed = ["credits", "category", "country", "date", "episode-num", "icon", "length", "previously-shown", "rating", "star-rating", "url"]
for programme in root.findall(".//programme"):
for element_name in not_needed:
elements = programme.findall(f".//{element_name}")
for element in elements:
if element in programme:
programme.remove(element)
edited_tv_programs = ET.tostring(root, encoding='unicode')
# kiszedi a clumpidx="0/1"-et
edited_tv_programs = re.sub(r' clumpidx=.*\"', r'', edited_tv_programs)
# kiszedi a (0.)-át
edited_tv_programs = re.sub(r'<desc lang="hu">(\(.*\.\) )', r'<desc lang="hu">', edited_tv_programs)
# kiszedi a ...-ot
edited_tv_programs = re.sub(r'<desc lang="hu">(\.\.\. )', r'<desc lang="hu">', edited_tv_programs)
with open('edited.xml', 'w', encoding='utf-8') as file:
file.write(edited_tv_programs) -
sztanozs
veterán
válasz Atomantiii #4232 üzenetére
sajna google drive (se onedrive, se pastebin) sem jatszik...
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...
-
sztanozs
veterán
válasz Atomantiii #4234 üzenetére
nope de ranezek majd este otthonrol, ha el nem felejtem...
[ 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...
-
Adott egy Python program. Raspberry-n fut, és az IO lábakon keresztül vezérel 2 relésort (4db "zöld", és 4db "piros"). A parancsokat egy másik program adja neki hálózaton. Szépen rendben teszi is a dolgát, és kapcsolgatja a reléket. A relék kimenete egy "utasító"ra van kötve, amin keresztül kommunikálni lehet az operatőrökkel. Ez az eszköz képes a kamerákhoz tartozó piros/zöld lámpák vezérlésére.
Sajnos a gyárban valamit nagyon elkeféltek, mert ha azt a parancsot kapja, hogy a kamerán egyszerre világítson a zöld és a piros lámpa, akkor az zöld marad, holott a pirosnak kellene prioritást kapni, hiszen azzal jelzik neki, hogy ne igazgassa ide oda kamerát, mert "adásban van". Remélem érthető bevezője volt ennek a kódnak.
Arra tippelek, hogy a 156. sornál kezdődő résznél lehet a megoldás kulcsa.def setStates():
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
for gpo_group in config_object["gpo_groups"]:
for gpo in gpo_group["gpos"]:
GPIO.setup(gpo["pinNumber"], GPIO.OUT)
GPIO.output(gpo["pinNumber"], getOutputValue(False))
gpo["lastState"] = False
Szerintem ide kellene egy ellenörzést beiktatni, hogy abban az esetben ha "gpo_groups"-on belül mindekkető be van kapcsolva (a zöld "preview", és piros "program" is), akkor a zöldet kapcsolja ki, és csak a piros legyen bekapcsolva. Jó irányba kapisgálok?
[ Szerkesztve ]
Freeware, és akciós programok egy helyen https://www.facebook.com/freewarenews
-
kovisoft
őstag
Szerintem nem a setStates függvény az, amit keresel. Ha megnézed, a setStates és a GPO_off gyakorlatilag pont ugyanazt csinálja: kikapcsolja az összes bekonfigurált pint. És a setStates csak induláskor van egyszer meghívva, miután a konfig be lett olvasva.
Nem értem, hogy pontosan hogyan működik maga a program, hogyan lehet neki utasításokat adni, de szerintem a GPIO.output hívásokat kellene végignézned, hogy melyik lehet az, amelyik neked a lámpákat vezérli, és oda lehetne betenni egy olyan feltételt, hogy a zöldet ne kapcsolja, ha egyúttal a pirosat is kellene kapcsolnia. Ez valószínűleg a processTallyData lehet, mert az on_flash ránézésre egyetlen pint villogtat.
-
válasz kovisoft #4238 üzenetére
Aha... Köszi!
A projekt "fő" programja, a tallyarbiter. Ez kommunikál a képkeverővel, figyeli a megadott csatornák állapotát. Egy csatonának 2 "állapotjelzője" van:
-preview csatonára kapcsolva
-program csatornára kapcsolva
A képkeverő csatornáinak az állapotát küldi el a "kliens" programkonak. Ez lehet egy mikrovezérlő(vel egybeépített színes LED), vagy egy relé modul,...
Esetemben a Pi-re kötött relé modul pedig a kapott adatoknak megfelelően kapcsolgatja ki/be a zöld/piros lámpákat attól függően, hogy a képkeverőn hogyan kapcsolták preview vagy program csatornára a kamerákat.A valóságban egyszerübb mint itt elmesélni, leírni a működését
Nézegetem ezt a processTallyData() fügvényt, de mint az a bizonyos borjú az új kapura ... Valahogy nem megy a kód értelmezése (a Python (szemantika) ismeretének hiánya is nehezíti, hogy most éppen mire gondolt a költő: powered_pins.append(gpo["pinNumber"])
Miért van eltárolva a "bekcsolt" lábak listája?
Miért van két külön ciklus a be ill. a kikapcsolásra?
Hová kéne berakni a plussz ellenörzést, és hogyan? Hiszen a ciklus végimegyaz összes előre definiált IO porton. Hogyan ellenörzöm, hogy az adott pi "program"kimenetnek van kapcsolva, vagyis a hozzá tartozó "preview" kimenetet ki kell kapcsolni?Erre még aludni kell párat ...
[ Szerkesztve ]
Freeware, és akciós programok egy helyen https://www.facebook.com/freewarenews
-
kovisoft
őstag
Én sem vágom, hogy itt ki kinek mikor mit küld, mit hív, stb. De szerintem az első cikus végzi a device_state-ben megkapott device-ok megadott pin-jeinek a bekapcsolását. És a powered_pins-ben összegyűjti azokat a pin-eket, amiket bekapcsolt. Utána a második ciklus pedig azt csinálhatja, hogy végigmegy az összes device összes pin-jén, és azokat kikapcsolja, amiket az első ciklus nem kapcsolt be. Azaz a végére pontosan azok lesznek bekapcsolva, amiknek bekapcsolva kell lenniük, az összes többi pedig ki lesz kapcsolva.
Tehát ha jól gondolom, akkor az első ciklusba tudnál betenni valami feltételvizsgálatot, hogy ha be tudod azonosítani azt az eszközt és a pin-eket, amik a zöld és piros lámpákat jelentik, akkor a zöldet ne kapcsolja be, ha a pirosat be kellene kapcsolni.
Nem tudom, meg lehet-e oldani mondjuk, hogy a konfigban hamarabb szerepeljen a piros lámpa pin-je, mert akkor mire a zöldre kerül a ciklus, addigra már lehetne látni, hogy a pirost be kell-e kapcsolni.
Ha ez nem járható út, akkor esetleg csinálhatsz az egész elé egy harmadik ciklust, ami kb. ugyanazt csinálja, mint a mostani első ciklus, de ténylegesen nem kapcsol pin-t, csak megjegyzi egy változóban, hogy a pirosat be kellene-e kapcsolni. És ha ez a változó be van állítva, akkor a bekapcsoló ciklusban kihagyja a zöldet.
Persze ehhez tudni kellene, hogy tényleg a processTallyData az a függvény, ami a kapcsolgatást végzi. Ezt mondjuk ki tudod próbálni, ha kikommentezed benne a bekapcsolást, és attól elmúlik a lámpák bekapcsolása.
-
axioma
veterán
-
kovisoft
őstag
Ez villogást (vagy ha nem lámpáról lenne szó, akkor egyéb mellékhatást) okozhatna, valószínűleg az sem véletlen, hogy nem azt csinálja a program, hogy először mindent kikapcsol, aztán bekapcsolja azokat, amiket be kell. De persze, ha ez nem zavaró, akkor úgy is lehet csinálni, ahogy írod.
-
axioma
veterán
válasz kovisoft #4242 üzenetére
Hm, jogos, latszik h csak a logikai vegeredmenyt neztem nem vagyok hardverhez szokva...
Akkor is megoldhato kettoben: elsore nem kapcsol csak gyujti, masodikban meg kapcsol mind2 iranyban, csak a zold kivant allapotat update-eli a set-beli allapothoz kepest a muvelet elott.[ Szerkesztve ]
-
A példa kedvéért tegyül fel, hogy az 1,3,5,7 lábak vezérlik a piros lámpákat, a 2,4,6,8 pedig a zöldeket. Az első csatornához tartozik a 1,2, a második csatornához a 3,4,...
# Ha az első piros lámpa bekapcsolódik
if pinNUmber = 1:
# Kikapcsolja a hozzá tartozó zöldet
powered_pins.remove(2)
powered_pins.append(gpo["pinNumber"])
Ha a piros lámpát bekapcsolja, a hozzá tartozó zöld lámpa sorszámát kiveszi a powered_pins listából, így a következő ciklusban kikapcsolja a hozzá tartozó zöldet. (Nem fut hibára, ha egy nem létező elemet vennék ki?) Viszont semmi nem garantálja, hogy a piros lámpa után, a rákövetkező ciklusban nem a csatornához tartozó zöld lámpát olvassa be, ami visszakapcsolhatja.
Ezért az ellenörzést, kikapcsolást, inkább a két ciklus közé kellene tenni, amikor már minden bekapcsolt relét tartalmazó lista elkészült.# Ha a az első piros lámpa bekapcsolódik
if 1 in powered_pins:
# Kikapcsolja a hozzá tartozó zöldet
powered_pins.remove(4)
Vagy be lehet passzítani valahogy az első listába, amikor a powered_pins készül?Megoldható, hogy ne legyen beégetve a IO láb sorszáma, hanem a .json fájlból beolvasott értékekkel hivatkozzak rá?
[ Szerkesztve ]
Freeware, és akciós programok egy helyen https://www.facebook.com/freewarenews
-
kovisoft
őstag
Az if-ben dupla == az egyenlőségvizsgálat.
A json konfig mintában azt látom, hogy csak deviceId-k és azon belül pinNumber-ök vannak definiálva, ezzel a konfiggal leginkább csak hardkódolni tudod. De ha kiegészítheted a konfigot, akkor felvehetsz plusz attribútumokat, amikkel megadhatod, hogy az adott device vagy az adott device adott pin-je milyen másik device milyen pin-jével nem működhet együtt. Pl. a "pinNumber" mellé felvehetsz egy "conflictingDeviceId" és egy "conflictingPinNumber" mezőt. Ide beírod, hogy mivel nem tud együtt működni. A kódban pedig gpo["conflictingPinNumber"]-ként tudsz rá hivatkozni.
-
-
A két ciklus közé kellett ez a pár sor, és most úgy működik, ahogy szeretném.
# Ha a ch1 piros, kikapcsolja a ch1 zöldet
if 14 in powered_pins and 16 in powered_pins:
powered_pins.remove(16)
# Ha a ch2 piros, kikapcsolja a ch2 zöldet
if 4 in powered_pins and 26 in powered_pins:
powered_pins.remove(26)
# Ha a ch3 piros, kikapcsolja a ch3 zöldet
if 3 in powered_pins and 20 in powered_pins:
powered_pins.remove(20)
# Ha a ch4 piros, kikapcsolja a ch4 zöldet
if 2 in powered_pins and 21 in powered_pins:
powered_pins.remove(21)
Köszönöm a segítséget, útba igazítást!
Freeware, és akciós programok egy helyen https://www.facebook.com/freewarenews
-
Blasius
tag
Sziasztok,
Egy egyszerű kódot szeretnék futtatni microPythonban egy openWRT routeren:
import socket
soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
soc.bind(('', 2215))De már a harmadik sorban elakadtam, és ezt a hibaüzenetet kapom:
TypeError: object with buffer protocol requiredUgyanaz a hibaüzenet a routeren is és egy linuxos gépen is. Rendes pythonban jól megy.
Mi lehet a probléma a microPythonban?Ha ''a'' ram megy dualban ''b'' rammal, és ''c'' ram megy dualban ''b'' rammal, akkor ''a'' ram megy dualban ''c'' rammal?
-
sztanozs
veterán
válasz Blasius #4248 üzenetére
https://forum.micropython.org/viewtopic.php?t=1779
es
upython socket docs:
https://github.com/micropython/micropython/blob/master/docs/library/socket.rst[ 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...
Új hozzászólás Aktív témák
Állásajánlatok
Cég: PCMENTOR SZERVIZ KFT.
Város: Budapest