Hollosi Information eXchange /HIX/
HIX CODER 602
Copyright (C) HIX
1999-10-06
Új cikk beküldése (a cikk tartalma az író felelőssége)
Megrendelés Lemondás
1 VB + Mailing (mind)  16 sor     (cikkei)
2 RE:RE: binaris fa (mind)  29 sor     (cikkei)
3 Binaris fa, 1 megoldas a sokbol (mind)  53 sor     (cikkei)
4 Re: Delphi -form (mind)  18 sor     (cikkei)
5 CGI & Perl ( 8 sor ) (mind)  12 sor     (cikkei)
6 Long Int szorzasra reagalasok (mind)  31 sor     (cikkei)
7 Visual C++ (mind)  25 sor     (cikkei)
8 Gond egy BIOS-hivassal (mind)  31 sor     (cikkei)
9 Re: Binaris fa (mind)  23 sor     (cikkei)
10 Delphi koszonet (mind)  9 sor     (cikkei)
11 RE: Binaris fa (mind)  51 sor     (cikkei)
12 VU meter +VB (mind)  14 sor     (cikkei)
13 Re: Binaris fa (mind)  55 sor     (cikkei)
14 Re: Long int overflow (mind)  37 sor     (cikkei)
15 Re: Binaris fa (mind)  82 sor     (cikkei)
16 ms -> borland (mind)  5 sor     (cikkei)
17 lebegopontosbol egesz (mind)  15 sor     (cikkei)
18 Re: Binaris fa (mind)  18 sor     (cikkei)
19 Re: long int owerflow -->Mc (mind)  17 sor     (cikkei)

+ - VB + Mailing (mind) VÁLASZ  Feladó: (cikkei)

Sziasztok!

A kovetkezo kerdesem lenne: egy olyan programot szeretnek
irni VB-ben, mely tudja kezelni az SMTP es a POP3 szervereket,
valamint erti a MIME protokollt. Elviekben lehetseges az, hogy
miutan a Tarcsazoval felpattan egy szerverre, utanna a Winsock
segitsegevel tudjon kommunikalni. Gyakorlatban ez megvalosithato?
Ha jol tudom, az interneten a szamitogepek egymas kozt is tobbnyire
ascii, vagy legalabbis szoveges uzemmodban kommunikalnak.
Ez valoban igy van, vagy marha nagy hulyeseget mondtam?

Kerem, aki valamennyire jartas ebben a dologban, segitsen nekem!

Elore is koszonom!

NagyMacs
+ - RE:RE: binaris fa (mind) VÁLASZ  Feladó: (cikkei)

Udv

koszonom a leveleket.

A valaszok szerint a gond itt volt:
>>>
	if (csomo==NULL)
	{
		//új elem felvitele
		//nincs értékadás???
		csomo=(struct tCsomo*)malloc(sizeof(struct tCsomo));
		csomo->Elem=Elem;
		csomo->Bal=NULL;
		csomo->Jobb=NULL;
	}
<<<

na most azt nem ertem, hogy ha van egy fv. es atvesz egy pointer
- jelen esetben csomo*, ami egy felsobb csomo bal, vagy jobb 
oldali aga (ill. annak pointere) - es az a sor, hogy
csomo=(struct tCsomo*)malloc(sizeof(struct tCsomo));
nem ad neki erteket? Hat a malloc helyet foglal, es visszaadja
a lefoglalt hely cimet, BELE a csomo-ba, es mivel pointer vett at
annak erteke meg kene, hogy maradjon, nem?
Elnezest ha gyoker vagyok, de egyszeruen nem ertem.
                                                    bye...
> ----------------------------------------------------------
E-Mail: 
PMail32 v3.12a
+ - Binaris fa, 1 megoldas a sokbol (mind) VÁLASZ  Feladó: (cikkei)

Koszonom a valaszokat, nagyon sokat segitettetek!!!

"Eberhardt Gergely (VBuster)" >
irta a szivemhez legkozelebb allo 'pach'-et. Amikor le
akartam kuzdeni a problemat szerintem erre gondoltam:

>>>
void Beszur(int Elem, struct tCsomo **csomo)
{
	//paraméterek: az elem értéke és az aktuális csomópont
	if (*csomo==NULL)
	{
		//új elem felvitele
		*csomo=(struct tCsomo*)malloc(sizeof(struct tCsomo));
		(*csomo)->Elem=Elem;
		(*csomo)->Bal=NULL;
		(*csomo)->Jobb=NULL;
	}
	else
	{
		//rekurzív hívás a rendezettségnek megfelelően
		if (Elem< (*csomo)->Elem)
		{
			Beszur(Elem, &((*csomo)->Bal));
		}
		else
		{
			Beszur(Elem, &((*csomo)->Jobb));
		}
	}
}

void main()
{
	struct tCsomo *Fix = NULL;

	Beszur(0, &Fix);
	Beszur(10,&Fix);
	Beszur(-10,&Fix);

	PreOrderLista(&Fix);
}
<<<

mindenkinek koszi, koszi, koszi:
	Daniel Barna >
	Tibor VELENCEI >
	Mihály Zoltán >

                                                    bye...
> ----------------------------------------------------------
E-Mail: 
PMail32 v3.12a
+ - Re: Delphi -form (mind) VÁLASZ  Feladó: (cikkei)

Udv!
Szerintem az a legjobb, ha csinalsz egy formot, a megfelelo kutyukkel
(ProgressBar, Label,...), es vhogy igy hivod meg:

MessageForm := TMessageForm.Create;
Label1.Caption := 'csak turelem...';
MessageForm.Show;
{...}
MessageForm.Hide;
MessageForm.Free;

a {...} helyere pedig beteszed az idoigenyes programkodot. A form
propertyjeit pedig meg pr. iraskor beallitgatod.

Udv:
Gaby
______________________________________________________________________
http://www.sch.bme.hu/~gyoreg  mailto:  ICQ#:19934854
+ - CGI & Perl ( 8 sor ) (mind) VÁLASZ  Feladó: (cikkei)

> Szoval Perl-ben irogatok valamiket, de CGI-n keresztul kell hogy kapja
> az adatokat. Szoval vannak valami specialis valtozok, vagy valami
> header resz vagy valami ami hasznalnom kell a perl programomba, vagy 
> egyszeruen atnevezem a *.pl-rol *.cgi-re, es meg van oldva a dolog?

Nem egeszen. Annyi a kulonbseg, hogy a cgi-nel a kiiras elott kell egy
print "Content-type:text/html\n\n"; sor. Persze ha plain textet kuldesz,
akkor text/plain. Vagy: text/css, meg minden ilyesmi.

Gaby
______________________________________________________________________
http://www.sch.bme.hu/~gyoreg  mailto:  ICQ#:19934854
+ - Long Int szorzasra reagalasok (mind) VÁLASZ  Feladó: (cikkei)

Tisztelt CODER!

Koszonom a sok segitokesz valaszt a "long int szamok szorzasanak
ellenorzesere" feltett kerdesemre. Nekem ez a ket megoldas tetszik a
legjobban, ha az osztas muvelete nem tul "draga" :


1. Daniel Barna küldött egy jó megoldást, o elo"osztassal 
korlatozza a megengedett bemeneti adatokat:

 long a,b,c;

 a=...;
 b=...;
 if( b == 0  ||
     (('a' es 'b' azonos elojelu) && abs(a)<=LONG_MAX/abs(b)) ||
     ((a es b ellentetes elojelu) && abs(a)<=-LONG_MIN/abs(b)))
   {
  c = a * b;  /* no overflow */
 }

2.   pedig utolag ellenorizteti az eredmenyt 
osztassal:

>Talan ha a vegeredmenyt leosztod valamelyik tenyezovel es
>osszehasonlitod a masikkal? 

Ez lehet, hogy meg rovidebb, termeszetesen itt is ki kell zarni a 
0-val valo osztast.

                       Aggod Jozsef
+ - Visual C++ (mind) VÁLASZ  Feladó: (cikkei)

Sziasztok!
Nehany hete kezdtem tanulni a VC++ -t.
Eddig csak adatbaziskezelokkel foglalkoztam (DOS alatt) ill. Qbasic es egy
keves Pascal ismeretem van.
A visual es objektumorientalt dolgokbol eddig nem sok ragadt ram.

A segitsegeteket kernem ezzel kapcsolatban:
tudnatok-e javasolni modszereket ill. segedeszkozoket (konyvek, doksik,
tutorok, peldak, CD-k, helyek a Neten,...esetleg egy-ket sajat peldaprogi
stb... stb...) amikkel egyreszt a leglenyegesebb es leggyakrabban hasznalt
dolgokat ki tudom szurni a kevesbe lenyegesek kozul, masreszt amikkel
viszonylag gyorsan es hatekonyan lehetne elore haladni.

Ne ertsetek felre, tudom, hogy "nem vezet kiralyi ut ..." es nem a
kuszkodest akarom teljesen megsporolni, csak nem akarok aranytalanul sok
idot tolteni olyan fogalmakkal amik csak minden szokoevben fordulnak elo. A
fontosakat pedig, honnan ill. hogyan erdemes tanulni ill. milyen melysegig.
Tudnatok nehany tippet adni ezzel kapcsolatban?

Tudom, hogy a kerdes altalanos es feladattol is fugg, de aki atlatja az
egeszet az gondolom tudja, hogy milyen modon lehetne hatekonyan eljutni a
lenyegig, vagy nem?
Maganba (is) kernem a valaszokat.
Halas koszonettel:
Gabor
+ - Gond egy BIOS-hivassal (mind) VÁLASZ  Feladó: (cikkei)

Van egy kis gondom. Egy programomban a szovegkiirasokat BIOS-hivasra
kellene cserelni, hogy felolvasoprogrammal kompatibilis legyen. A program
Power BASIC-ben van, amibe minden tovabbi nelkul betehetek inline
assemblyt. Viszont nem vilagos nekem a szoveg kezdocimenek atadasa. Ezt
talaltam a Tech Helpben az INT 10H funkcioi kozott:

13H Displays a string at a selected cursor position.
    Characters 0dH (CarRet), 0aH (LineFeed), 08H (bksp), and 07H (Beep) are   
    treated as control commands and are not displayed.                        
    Input: AH = 13H                                                           
           ES:BP => string to display (special format for AL=2 and AL=3)      
           CX = length of string (character count only)                       
           DH,DL = row,column to start displaying                             
           BH = page number                                                   
           AL = SubFn code:                                                   
                0 = use attribute in BL; don't update cursor                  
                1 = use attribute in BL; leave cursor at end of string        
                2 = string format: char,attr, char,attr...; no cursor update  
                3 = string format: char,attr, char,attr...; do update cursor

  Ezeket mind fel tudom tolteni gond nelkul, de BH-val es ES:BP-vel gondban
vagyok. Nekem a PB ket fuggvenyt biztosit, a STRSEG megadja a szoveg
szegmenset es a STRPTR az offszetet. Eloszor ugy probaltam, hogy MOV BH,
STRSEG; MOV ES, 0; MOV BP, STRPTR, de ebbol a masodik utasitasra helybol
szintaktikus hibat kaptam, nem ismer ilyen regiszternevet. Ettol
fuggetlenul nem hiszem, hogy jol csinaltam. A STRPTR tizenhat bites adatot
ad vissza, ezt tehat nemigen akarhatom ket tizenhat bites regiszterbe
tolteni csak ugy maupassant.
  Tekintve, hogy a regiszterek es az egesz memoriakezeles nekem mindig
kinaiul volt, magamtol nem tudom kiokoskodni a megoldast. Azt kernem,
maganban is valaszoljatok, nem olvasom a listat.
+ - Re: Binaris fa (mind) VÁLASZ  Feladó: (cikkei)

Vigyazat! A C-ben csak ertek szerinti parameteratadas letezik!
Ezert ha egy pointer parameter erteket valtoztatni akarod, akkor
pointerre mutato pointert kell visszaadnod:

void Beszur(int Elem, struct tCsomo **csomo)
{
        //paraméterek: az elem értéke és az aktuális csomópont
        if ((*csomo)==NULL)
        {
                //új elem felvitele
                (*csomo)=(struct tCsomo*)malloc(sizeof(struct tCsomo));
                (*csomo)->Elem=Elem;

 ... es igy tovabb. 

Meghivni pedig:

Beszur(10,&&Fix);

-el kell, ertelemszeruen.

Udv
	Szabolcs
+ - Delphi koszonet (mind) VÁLASZ  Feladó: (cikkei)

Hello

Szoval mindenkinek koszonom a megoldasait a Delphi
form-mal kapcsolatban.

Mostmar kiralyul mukodik.

Sir LanDy
mailto:
+ - RE: Binaris fa (mind) VÁLASZ  Feladó: (cikkei)

Hi!

Talan igy egy kicsit jobb lesz a dolog:

void Beszur(int Elem, struct tCsomo **csomo)
{
	//paraméterek: az elem értéke és az aktuális csomópont
	if (*csomo==NULL)
	{
		//új elem felvitele
		*csomo=(struct tCsomo*)malloc(sizeof(struct tCsomo));
		(*csomo)->Elem=Elem;
		(*csomo)->Bal=NULL;
		(*csomo)->Jobb=NULL;
	}
	else
	{
		//rekurzív hívás a rendezettségnek megfelelően
		if (Elem< (*csomo)->Elem)
		{
			Beszur(Elem, &((*csomo)->Bal));
		}
		else
		{
			Beszur(Elem, &((*csomo)->Jobb));
		}
	}
}

Ugyanis ha a Beszur-ban atadott pointernek akarsz erteket adni, akkor nem
art, ha a pointer cimet adod at, mivel ellenkezo esetben a Beszur megkapja
a csomo cimet, amit a stacken tarol. Ha ezek utan ezt a cimet irod at,
akkor az csak a stack-en valtozik meg, az eredeti helyen viszont nem.
Ebben az esetben termeszetesen a main is egy kicsit maskent fog kinezni:

void main()
{
	struct tCsomo *Fix = NULL;

	Beszur(0, &Fix);
	Beszur(10,&Fix);
	Beszur(-10,&Fix);

	PreOrderLista(&Fix);
}

Remelem nem irtam el semmit, es igy mar mukodni fog a dolog.

Eberhardt Gergely
Hungarian VirusBuster Team.
http://www.vbuster.hu mailto:
+ - VU meter +VB (mind) VÁLASZ  Feladó: (cikkei)

Hali

Tud-e valaki megoldast az alabbi problemara ?

Van  egy VB progi aminek egyszerre kellene hangot
rogzitenie, valamint a bemenetet megjeleniteni
valami kivezerlesmero felen. Kulon-kulon mindketto tokeletesen
mukodik, de egyutt mar NEM. Mindket programresz a WaveIn API
hivasait hasznalja. Ha elindul a felvetel a kivezerlesmero mar nem
indithato mivel a wavein device mar foglalt. A felvevo resz nem nagyon
valtoztathato meg, a Windows Media Audio encoderet
hasznalja. Otlet, hogy hogyan lehetne megkerulni ezt a problemat ???

Koszi
+ - Re: Binaris fa (mind) VÁLASZ  Feladó: (cikkei)

On  4 Oct 99 at 8:55,  wrote:

> Nos az a gondom, hogy nem megy... Szoval valahanyszor megivom a
> Beszur-t, a debug szrint mindig NULL a Jobb es Bal ag.
> Egyszeruen nem tudom elkepzelni, hogy miert van ez igy, hiszen az
> algoritmus az jo.

Az jo, viszont bug van a progidban:

> void Beszur(int Elem, struct tCsomo *csomo)
> {
>         //paraméterek: az elem értéke és az aktuális csomópont
>         if (csomo==NULL)
>         {
>                 //új elem felvitele
>                 csomo=(struct tCsomo*)malloc(sizeof(struct tCsomo));

Itt 'csomo' (* nelkul) a fuggveny aktualis parametere, pont olyan, 
mintha lokalis valtozo lenne. Tehat a fuggveny vegen megszunik!
Nem magat a pointert, hanem annak a cimet kellene atadnod, ugy tudod 
a pointert, es nem a stack-ben allokalt masolatat modositani.

Valami ilyesmit kellene csinalnod:
( struct tCsomo es PreOrderLista() maradhat ugyanugy, a tobbi pedig: )

void Beszur(int Elem, struct tCsomo **csomo)
{
   if (*csomo == NULL) {
      *csomo = (struct tCsomo*)malloc(sizeof(struct tCsomo));
      (*csomo)->Elem = Elem;
      (*csomo)->Bal = (*csomo)->Jobb = NULL;
   } else {
      if (Elem < (*csomo)->Elem)
         Beszur(Elem, &((*csomo)->Bal));
      else
         Beszur(Elem, &((*csomo)->Jobb));
   }
}

int main()
{
   struct tCsomo *Fix = NULL;

   Beszur(0,&Fix);  // A 0-as ag is malloc-kal allokalodik majd!
   Beszur(10,&Fix);
   Beszur(-10,&Fix);

   PreOrderLista(Fix);

   return 0;  // Illetlenseg elfeledkezni rola egy void main-nel!!
}

István
--  Istvan Marosi  --  http://www.sch.bme.hu/~marosi  --
--  Recosoft Ltd.  --  mailto:  --
+ - Re: Long int overflow (mind) VÁLASZ  Feladó: (cikkei)

On  4 Oct 99 at 20:01,  > wrote:

> On Sun, Oct 03, 1999 at 02:20:12AM +0000,  wrote:
> > Ha VC++ -t hasznalsz, akkor abban van 64 bites aritmetika is. Igy meg mar
> > konnyu a tulcsordulast vizsgalni
> 
> Es ha a 64 bit csordul tul?

:))

Ha 32 bites a vedendo aritmetika, akkor 64 biten nem fog
tulcsurdulni. Ennek ellenere en nem ugy csinalnam, hanem irnek egy
asm makrot (esetleg egy inline fuggveny belsejeben), ami mindezt 
elintezi. A hordozhatosagot ez nem bantja nagyon, nehany makroval meg 
el lehet banni, ha mas processzorra is at kell vinni a progit.

Pl. gcc-ben 386-os vagy nagyobb procin:

#define imul(sz1,sz2,szorzat,overflow) __asm__ ( \
  "imull %3,%0 \n\t" \
  "seto %1" \
  : "=r" (szorzat), "=m" (overflow)  /* output %0 es %1 */   \
  : "0" (sz1), "m" (sz2)             /* input %2=%0 es %3 */ \
)

   int egyik, masik, szorzat;
   char overflow;

   imul(egyik,masik, szorzat,overflow);

   if (overflow) {
      ....
   }

István
--  Istvan Marosi  --  http://www.sch.bme.hu/~marosi  --
--  Recosoft Ltd.  --  mailto:  --
+ - Re: Binaris fa (mind) VÁLASZ  Feladó: (cikkei)

Szia,

1. A Beszur-ban a csomo egy pointer tipusu valtozo, ami uj erteket kap 
   a malloctol, es sehova nem kerul vissza az erteke.

2. Kovetkezik az elozobol, hogy a balra jobbra beszuras -nal nem adod meg
   hogy hova szurja be a leveleket. (azazhogy megadod, de nem jon vissza,
   es szerintem ezen a ponton csusztal el: *csomo egy tCsomo-ra mutato 
   pointer, es ha ugy hivatkozol ra hogy csomo, akkor a lokalis pointerre
   hivatkozol, es nem kerul vissza ertek a parameterlistan keresztul.)

3. Ez nem feltetlen problema, de nem elegans, hogy a Fix-et a foprogiban
   statikusan deklaralod.

Tehat azert nem megy, mert 1., 2.-bol kovetkezoen a binaris fa osszefuzese
nem valosul meg.

Atirtam igy, nekem mukodott:

> struct tCsomo				//Az adatszerkezet
> {
> 	int Elem;				//az elem
> 	struct tCsomo *Bal;		//bal oldali ág
> 	struct tCsomo *Jobb;	//jobb oldali ág
> };
> 
> struct tCsomo *Beszur(int Elem, struct tCsomo *csomo)
> // igy fogom visszaadni a malloc erteket
> {
> 	//paraméterek: az elem értéke és az aktuális csomópont
> 	if (csomo==NULL)
> 	{
> 		//új elem felvitele
> 		csomo=(struct tCsomo*)malloc(sizeof(struct tCsomo));
> 		csomo->Elem=Elem;
> 		csomo->Bal=NULL;
> 		csomo->Jobb=NULL;
> 	}
> 	else
> 	{
> 		//rekurzív hívás a rendezettségnek megfelelően
> 		if (Elem< csomo->Elem)
> 		{
> 			csomo->Bal=Beszur(Elem, csomo->Bal);
> 		}
> 		else
> 		{
> 			csomo->Jobb=Beszur(Elem, csomo->Jobb);
> 		}
                     // itt valosul meg az osszefuzes!!!
> 	}
>       return csomo; // itt kerul vissza az uj cim;
> }
> 
> void PreOrderLista(struct tCsomo *gyoker)
> {
> 	//gyökérkezdő lista
> 	if (gyoker!=NULL)
> 	{
> 		printf("%d, ",gyoker->Elem);
> 		PreOrderLista(gyoker->Bal);
> 		PreOrderLista(gyoker->Jobb);
> 	}
> }
> 
> void main()
> {
> 	struct tCsomo *Fix;  // ez legyen szinten dinamikus!
> 
>       Fix=NULL; // kezdeti ertekadas, konnyu kifelejteni, de fontos :)
>
>       Fix=Beszur(0,Fix);  // fix elem beszurasa 
>
> 	Beszur(10,Fix);    // itt mar nem szukseges erteket fogadni,
> 	Beszur(-10,Fix);   // mert ide az eredeti Fix jonne vissza,
>                           // ami mar nem fog valtozni.
> 	PreOrderLista(Fix);
> }
> 

udv:
kopper.
+ - ms -> borland (mind) VÁLASZ  Feladó: (cikkei)

Sziasztok,

Koszonom a subjectbeli velemenyeket ;)

kopper.
+ - lebegopontosbol egesz (mind) VÁLASZ  Feladó: (cikkei)

Hello Coderek!

Egy programot irok asm-ban, ami kiszamol egy lebegopontos szamot, de azt
nekem egesz szamuva kene konvertalni (mert ugye pl.: 234.45-os szin
nincsen)... tudnatok segiteni?

Ja, es meg itt megkerdezem, hogy hogy is vannak az FPU regiszterei es
hogyan lehet oket hasznalani? Mert amikor MOV-val probaltam vmi
SP-felebe irni, a TASM szepen hazavagott... :(((((

Udv
-- 
 Tamas Selmeci / TOR][UM 
mailto: 
    F0 0F C7 C8 rulez!
+ - Re: Binaris fa (mind) VÁLASZ  Feladó: (cikkei)

Szia Mephysto!

>void Beszur(int Elem, struct tCsomo *csomo)
>{
> //paraméterek: az elem értéke és az aktuális csomópont
> if (csomo==NULL)
> {
> //új elem felvitele
> csomo=(struct tCsomo*)malloc(sizeof(struct tCsomo));

A gond ott van, hogy a Beszur masodik parameteretol azt varod el, hogy
az uj erteket amit a malloc szolgaltat, a hivonak visszaadja. Pedig itt
ertek szerinti atadas van, pointer erteket adtal at. Pointer pointere lenne
az egyik helyes megoldas, vagy ird at ugy a fuggvenyt, hogy a visszatero
ertek legyen az uj csomo pointer es azt hasznald a hivo szintjen.

Szia Joco

+ - Re: long int owerflow -->Mc (mind) VÁLASZ  Feladó: (cikkei)

Hi inet,"HIX CODER" >!

iC> Tud-e valaki egyszeru es nagyszeru modszert C-ben 2 db.  long int  szam
iC> szorzatanak tulcsordulasvizsgalatara? Az elojelvizsgalat nem eleg, mert a
iC> tulcsordult eredmeny lehet jo elojelu is. Koszonettel:
mov eax,szam1
mov ecx,szam2
mul ecx
seto [tulcsordult]
mov [di+0],eax
mov [di+4],edx
;ez a kis kodocska osszeszoroz ket 32 bites szamot, es kiad magabol
;egy db 64 biteset, a szorzat pontos eredmenyevel, es egy db 8 biteset,
;ami 1, ha tulcsorult... /ha a masodik movot kiveszed, akkor csak az
;also 32 bitet menti el...

Mc

AGYKONTROLL ALLAT AUTO AZSIA BUDAPEST CODER DOSZ FELVIDEK FILM FILOZOFIA FORUM GURU HANG HIPHOP HIRDETES HIRMONDO HIXDVD HUDOM HUNGARY JATEK KEP KONYHA KONYV KORNYESZ KUKKER KULTURA LINUX MAGELLAN MAHAL MOBIL MOKA MOZAIK NARANCS NARANCS1 NY NYELV OTTHON OTTHONKA PARA RANDI REJTVENY SCM SPORT SZABAD SZALON TANC TIPP TUDOMANY UK UTAZAS UTLEVEL VITA WEBMESTER WINDOWS