Pieniä kysymyksiä ohjelmoinnista

Liittynyt
16.10.2016
Viestejä
543
Mikä on "standardi" tapa tallentaa Android äpin tiedot pilvipalvelimeen? Mieluiten käyttäisin pilvipalveluna Azurea, vaikka se lienee vähän monimutkaisempaa kuin Google Cloudin käyttäminen. Mulla on mielikuvana, että Azuren päässä mulla olisi RESTful API esim. logic appsilla tai function appilla toteutettuna, joka hoitaisi datan siirtämiset Azure SQL -kannan kanssa. Android äppi sitten kommunikoisi tuon RESTful API:n kanssa. Onko tällainen arkkitehtuuri yhtään sinne päin? Puuttuuko jotain oleellista?
Aika järee ratkaisu. Itse tekisin jollain backend as a servicellä kuten Firebase tai Supabase.
 
Viimeksi muokattu:
Liittynyt
20.10.2016
Viestejä
403
Ok, kiitos vinkistä. Näyttää siltä, että Microsoft tarjoaa myös vastaavaa Azuressa Mobile App servicellään. Taidanpa kokeilla saanko sillä homman toimimaan.
 
Liittynyt
16.11.2020
Viestejä
2 565
Vaikka on alkuun hemmetin hidasta, niin noi pilvi-infrat ois minusta kannattavaa opetella naputtelemaan koodiksi. Sen jälkeen, kun on naputellut jonkun geneerisen bäkkäri-infran kerran koodiksi, niin siitä on huomattavasti iloa siinä vaiheessa, kun tarvii jotain vastaavaa seuraavan kerran. Ja infran ylläpitokin on muutamaa kertaluokkaa mukavampaa koodilla (ja versionhallinnalla), kuin että joku sekava seurakunta käy sähläämässä vuorotellen konsolissa kuka mitäkin :D

Näköjään onnistuu Firebasenkin konffiminen (ainakin jollain tasolla) Terraformilla ja sen google providerilla. Kun olis aikaa, niin olis mielenkiintoinen testailla, kun kiinnostais tuo Firebase muutenkin (yhden pikkudemon vaan tehnyt).
 
Liittynyt
20.06.2017
Viestejä
1 853
Interaktiivisen päätöspuun tekoon etsiskelen työkalua. Jotain aika yksinkertaista, tehdään valinta ja seuraava taso ilmestyy näkyville, jolloin taas valinta jne. Löysin GoJS mutta sillä näyttäisi olevan nelinumeroinen hintalappu. Ei varmaan olisi kovin iso juttu vääntää jotain kertakäyttöistä sopivalla JS-kirjastolla mutta tuskin tuo GoJS on ainoa suunnilleen valmis työkalu. Eli suosituksia ottaisin vastaan.
 
Liittynyt
07.01.2021
Viestejä
678
Löytyisikö jotain lisäosaa tjsp jolla saisi automatisoitua helposti eri sivustoilta hakemisen? Siis käytännössä voisi komentaa lisäosassa, että avaa osoite X, kirjoita tuohon kenttään annettu hakuehto ja paina tuota nappia. Ja tämä toistetaan n:lle sivustolle.
 
Liittynyt
03.07.2018
Viestejä
347
Nyt erikoinen visa mysql-tietäjälle.
Olen käyttänyt devissä php 7.2 + mysql:ää ja eräs ohjema alkoi nyt sanomaan että " Field 'money' doesn't have a default value"
Katsoin koodia ja siinä ei ole koskaan ollut arvoa insert-lauseessa koska arvo lisätään vasta insertin jälkeen erillisellä update:lla.
Päivitin devin muutama päivä sitten php 7.4:een, mutta mysql:n versio ei muuttunut.
Production-palvelimella tuo toimii, vaikka eihän tuon pitäisi toimia ollenkaan, vai onko siihen jokin FLAG ? olisi kiva tietää että wtf
 
Liittynyt
17.10.2016
Viestejä
5 331
Nyt erikoinen visa mysql-tietäjälle.
Olen käyttänyt devissä php 7.2 + mysql:ää ja eräs ohjema alkoi nyt sanomaan että " Field 'money' doesn't have a default value"
Katsoin koodia ja siinä ei ole koskaan ollut arvoa insert-lauseessa koska arvo lisätään vasta insertin jälkeen erillisellä update:lla.
Päivitin devin muutama päivä sitten php 7.4:een, mutta mysql:n versio ei muuttunut.
Production-palvelimella tuo toimii, vaikka eihän tuon pitäisi toimia ollenkaan, vai onko siihen jokin FLAG ? olisi kiva tietää että wtf
Olisikohan tästä kyse:
 
Liittynyt
03.07.2018
Viestejä
347
Olisikohan tästä kyse:
Niinpäs olikin. Tietokanta on vanha kuin mikä ja sarakkeet sen mukaiset. Ilmeisesti jossain dev-serverin conffissa oli aiemmalle php-versiolle laitettu sql-mode eri arvoihin mitä tässä uudemmassa.
 
Liittynyt
23.12.2019
Viestejä
125
Onko terminaalissa muuten mahdollista tehdä kansion sisään esim 50 kansiota lisää, ja sitten siirtää esim kuvat siitä kansiosta noihin kansioihin? Esim jos 5000 kuvaa kansiossa, niin että vaikka 100 kuvaa jokaisessa alikansiossa.

Mac käytössä.
 
Liittynyt
21.01.2017
Viestejä
227
Tarkoitatko jotain tuollaista:
Koodi:
for (( X=1; X<51; ++X ))
do
  mkdir aa$X
  let Y=0
  for F in *.jpg
  do
    mv $F aa${X}/
    let Y=Y+1
    if [[ $Y == 100 ]]
    then let Y=0 ; break ; fi
  done
done
 
Liittynyt
01.01.2018
Viestejä
1 117
Käytättekö te noita vscoden tai chromen debuggereita kuinka usein tai ollenkaan? Ainakin c puolella kun sitä joskus käytin debuggereita oli kiva ja hyödyllistä käyttää. Mutta ainakin tuo vscoden debuggering watch window on aika hidas päivitymään webbi devauksen osalta. Eli aika harvoin tulee käytettyä.
 
Liittynyt
07.01.2021
Viestejä
678
Olen käyttänyt useammankin kielen kanssa. C:n kanssa en, kun ne hommat tahtoo olla sulautettua, niin niissä on ihan omat debuggerinsa. Mutta esimerkiksi Pythonin ja JavaScriptin kanssa ei ole ollut kummempia ongelmia.
 
Liittynyt
01.02.2017
Viestejä
747
Accessibilitystä. Jos html tagiin on hyvä eli pitää laittaa lukijoita varten esim lang="fi" jos sivulla on suomenkielistä tekstiä, niin onko jotain tagia jos on joku englanninkielinen blokki sen saman suomalaiseksi määritellyn alla?
 
Liittynyt
17.10.2016
Viestejä
5 331
Accessibilitystä. Jos html tagiin on hyvä eli pitää laittaa lukijoita varten esim lang="fi" jos sivulla on suomenkielistä tekstiä, niin onko jotain tagia jos on joku englanninkielinen blokki sen saman suomalaiseksi määritellyn alla?
Eikös tuo pitäisi mennä ihan niin että kun määrittelee koko dokumentin kielen <html lang="fi"> ja sitten esimerkiksi kappaleelle <p lang=en"> tms.
 
Liittynyt
17.10.2016
Viestejä
14 550
Accessibilitystä. Jos html tagiin on hyvä eli pitää laittaa lukijoita varten esim lang="fi" jos sivulla on suomenkielistä tekstiä, niin onko jotain tagia jos on joku englanninkielinen blokki sen saman suomalaiseksi määritellyn alla?
Tämä vastannee suoraan kysymykseesi:


Eli juuri kuten tuossa todettiin, että hierarkisesti määrittelet sen kielen. Jos on joku blokki muulla kielellä, niin annat sen blokin ympäröivälle elementille poikkeava kieli.
 
Liittynyt
01.02.2017
Viestejä
747
Tässä kun on harjoitellut tuota Reactia, niin on tullut kauhisteltua tuota pakettien määrää ja samalla myös noiden aukkojen.
Mikä lienee paras tapa Reactin käytöön. Kasata itse, käyttää esim Viteä? Onko jotain versiota mitä kannattaisi käyttää tuotannossa?

Toiset ohjeet sanoo että pitäisi joka päivä päivittää uusimpaan paketit, mikä tietenkin onnistuu kun yksin teen. Olisiko siis jossain tiimissä sovittu joku package-lock.json mitä käytetään. Tietenkin olen kuullut kauhutarinoita nyypiöistä niin kuin minä (ja kokeillutkin), jotka tulee projektiin ja pistää päivittäen koko projektin... itsellä ei ole tiimityöstä vielä mitään kokemusta, niin mitä olisi parhaimmat tavat?

Tästä on varmaan keskusteltu webbidevaus-podcastissa, mutta oon vasta jaksossa alle 30 :)
 
Liittynyt
01.01.2018
Viestejä
1 117
Tässä kun on harjoitellut tuota Reactia, niin on tullut kauhisteltua tuota pakettien määrää ja samalla myös noiden aukkojen.
Mikä lienee paras tapa Reactin käytöön. Kasata itse, käyttää esim Viteä? Onko jotain versiota mitä kannattaisi käyttää tuotannossa?

Toiset ohjeet sanoo että pitäisi joka päivä päivittää uusimpaan paketit, mikä tietenkin onnistuu kun yksin teen. Olisiko siis jossain tiimissä sovittu joku package-lock.json mitä käytetään. Tietenkin olen kuullut kauhutarinoita nyypiöistä niin kuin minä (ja kokeillutkin), jotka tulee projektiin ja pistää päivittäen koko projektin... itsellä ei ole tiimityöstä vielä mitään kokemusta, niin mitä olisi parhaimmat tavat?

Tästä on varmaan keskusteltu webbidevaus-podcastissa, mutta oon vasta jaksossa alle 30 :)
Olen itse käyttänyt vain tuota create-react-app skriptiä joka käyttää kai webpackkia.

Tietty jos haluaa serverside rendausta tai staattista sivua niin esim. Nextjs on ihan hyvä vaihtoehto.

Package. Jsonissa lukee mitä versiota se päivittää ^ tuolla merkillä. En osaa sanoa noista kuka päivittää, veikkaisin että projektin leadit noita arvioi.
 
Liittynyt
07.01.2021
Viestejä
678
Itselläkin nyt vasta ensimmäinen React-softa työn alla, mutta tuolla create-react-appilla pääsi näppärästi alkuun. Toki jotkut gurut ovat sitä mieltä, että sitä ei saisi käyttää.

En kyllä alkaisi päivittämään joka päivä paketteja, varsinkin jos on nyyppä. Saattaa mennä turhan paljon aikaa siihen että korjailee rikkoutuneita toimintoja. Vaikka noin yleisesti olenkin CI:n kannalla.

Toinen noista webbidevauksen päläjättistä on muuten entinen työkaveri.
 
Liittynyt
21.10.2016
Viestejä
9 054
Olisiko siis jossain tiimissä sovittu joku package-lock.json mitä käytetään.
Abauttiarallaa noin. package-lock kulkee repossa mukana. Repossa voi olla myös editori-asetuksiakin, notta kaikilla on formaatit&säännöt samallalailla automaagisesti (yleensä olettaen, että käytetään esim. vscodea). Tiimeissä/projekteissa on kyllä ohjeistukset/dokumentaatiot tehty alkuvaiheessa ja niitä ylläpidetään koko projektin eliniän ajan, että juurikin uudetkin jäsenet pääsee mukaan ilman, että tarvii joka asiaa käydä läpi yhdessä. Yleensä kyllä ainakin omalla kohdalla ollut tapana, että joku ottaa hoitaakseen uuden jäsenen briiffauksen, jossa käydään koodia ja käytäntöjä läpi ja katsotaan kaikki tärkeimmät linkit mm. dokumentaatioon ym yhdessä.

e: pointtina se, että ei noita iha hirveenä kannata etukäteen murehtia. Tietty hyvä tietää, mitä se oma javascript-framework syö ja miten se toimii. Tiimityöskentely kyl sujuu, ku itsellä on perusteet hallussa ja osaa sopeutua. Ei ole yhtä ja ainoaa tapaa.
 
Viimeksi muokattu:
Liittynyt
17.10.2016
Viestejä
14 550
Tässä kun on harjoitellut tuota Reactia, niin on tullut kauhisteltua tuota pakettien määrää ja samalla myös noiden aukkojen.
Mikä lienee paras tapa Reactin käytöön. Kasata itse, käyttää esim Viteä? Onko jotain versiota mitä kannattaisi käyttää tuotannossa?
Vite on erittäin hyvä, valovuosia mukavampi ja helpompi ottaa käyttöön kuin Webpack, joten suosittelen vahvasti ellei ole erityistä syytä olla sitä käyttämättä. Kukaan ei jää kaipaamaan webpackiä kun siitä aika jättää. Toivottavasti pian.

En tiedä, mitä tarkoitat itse kasaamisella. Et varmasti pärjää ilman bundlaajaa (Webpack, Vite jne). Nuo totetuttavat myös deviserverin sun muita devaamista helpottavia ominaisuuksia kuten HMR.

Toiset ohjeet sanoo että pitäisi joka päivä päivittää uusimpaan paketit, mikä tietenkin onnistuu kun yksin teen. Olisiko siis jossain tiimissä sovittu joku package-lock.json mitä käytetään. Tietenkin olen kuullut kauhutarinoita nyypiöistä niin kuin minä (ja kokeillutkin), jotka tulee projektiin ja pistää päivittäen koko projektin... itsellä ei ole tiimityöstä vielä mitään kokemusta, niin mitä olisi parhaimmat tavat?
Hommahan menee niin, että kun uusi projekti luodaan, niin sinne asennetaan yleensä uusimmat vakaat versiot paketeista. Sitten kun tämä projekti viedään tuotantoon, niin pitäisi pitää huoli kahdesta asiasta: että paketit päivitetään tuoreisiin erityisesti tietoturvan takia ja ettei tuotannoitu versio mene samalla rikki. Nämä sotivat toisiaan vastaan. Muutama ratkaisuehdotus:
  • GitHubiin saa asennettua Dependabotin (tai Renovaten), jolle voi antaa oikeudet päivittää paketteja automaattisesti esim. minor-versioihin. Tämä helpottaa ylläpitoa todella paljon. Nuo voi konffata todella yksityiskohtaisesti omien tarpeiden mukaan. Tarvittaessa voi tehdä niin, että Dependabot luo vain PR:t muttei automergaa. Major-päivitykset voi jättää manuaalisesti tehtäviksi, sillä rikkovat usein koodia.
  • Testien oltava kunnossa, jotta repo ei mene rikki automaattisissa päivityksissä. Joskus minor-päivitys rikkoo silti paketin toiminnan, joten kaikkeen pitää varautua. Typescript auttaa tässä hieman kun tyyppitsekki ottaa osan rikkoontumisista ehkä kiinni.
  • Masteria ei kannata ehkä viedä automaattisesti tuotantoon.
Lock-tiedoston pointti on vain se, että saadaan tarkat versiot koko depsupuun paketeista - ei vain niistä jotka listattu package.json:iin. Siihen ei juuri kosketa manuaalisesti koskaan.
 
Liittynyt
01.02.2017
Viestejä
747
Kiitoksia hyvistä ajatuksista. Debendabot itselläki käytössä ja välillä tulee spostia. Vitellä olisin itsekin halunnut aloittaa nyt prokkiksen, mutta ei tietenkään toiminut oleellinen lisäosa sen kanssa eikä osannut korjata. Itse kasaamisella ehkä tarkoitan jotenkin että asentelee itse kaikki oleelliset, niin tietää mitä appi on syönyt. Tosin ehkä se on hyvä alussa harjoituksen vuoksi tehdä muutenkin. On vaan niin hirveä määrä noita riippuvuuksia että amatööriä huimaa.
 
Liittynyt
21.10.2016
Viestejä
9 054
Lock-tiedoston pointti on vain se, että saadaan tarkat versiot koko depsupuun paketeista
Mielestäni tärkeämpi (eikä "vain") pointti on se, että kun toinen repon ladattuaan pistää npm install, nii se lataa samat paketit, eikä mahd. tuoreempia. Toki tän voi toteuttaa niinkin, että määrittelee package.jsonissa tarkemmin, mitä tahdotaan. Etuna se, että on kontrollia siihen mitä päivitetään ja kuinka pitkälle (tarpeellista, jos tietää mitä tekee ja miksi, muuten tarpeetonta).
 
Liittynyt
17.10.2016
Viestejä
14 550
Mielestäni tärkeämpi (eikä "vain") pointti
Ei siis ollut tarkoitus vähätellä tuota. Se nimenomaan on tuon tärkein pointti, että tismalleen sama puu voidaan replikoida joka paikassa. Meinasin korostaa vain sitä, että siihen ei manuaalisesti kajota eikä sitä erityisesti "sovita". Mutta ehkä ymmärsin väärin tuon alkup. kysyjän kommentin lock-tiedostosta ja yhdessä sopimisesta. Käytännössä projektissa se lock-tiedosto päivittyy koko ajan kun devaajat päivittävät paketteja ja lokaalisti näkevät, että kaikki toimii ja puskevat sen masteriin.

Toki tän voi toteuttaa niinkin, että määrittelee package.jsonissa tarkemmin
Aika vaikea/työlästä olisi replikoidan lock-tiedoston toimintaa noin kun siellä lockissa on koko puu mukana eikä vain suorat depsut. Eli depsujen depsujen depsut ad infinitum. Mutta ne tärkeimmät voi lukita tietty package.jsonissa ja se voi joskus olla tarpeellista.
 
Liittynyt
21.10.2016
Viestejä
9 054
Aika vaikea/työlästä olisi replikoidan lock-tiedoston toimintaa noin kun siellä lockissa on koko puu mukana eikä vain suorat depsut. Eli depsujen depsujen depsut ad infinitum. Mutta ne tärkeimmät voi lukita tietty package.jsonissa ja se voi joskus olla tarpeellista.
No tuossa meinasin, että jos on tiedossa, että jotain ei voi/saa päivittää esim. minoreita enempää. En tietty tarkoittanut, että sillä tarkalleen ottaen lockia korvais, mut käytännön tasolla. Tällöin kukaan ei edes vahingossa päivitä. Siksi sulkeissa maininta asiasta.
 
Liittynyt
05.02.2017
Viestejä
176
Koodi:
enum IpAddrVersion {
    V4(u8, u8, u8, u8),
    V6(u16, u16, u16, u16, u16, u16, u16, u16),
}
type IP = IpAddrVersion;

impl IpAddrVersion {
    fn is_valid_v6(&self) -> bool {
        match self {
            Self::V4(_,_,_,_) => false,
            Self::V6(..) => true,
        }
    }
    
    // TODO
    fn regex_match_v6() -> bool {false}
    fn to_string() {}
    fn to_string_compressed() {}

    fn from_string(input: &String) -> IpAddrVersion {
        let v6_tuple: (u16, u16, u16, u16, u16, u16, u16, u16) = (0,0,0,0,0,0,0,1);
        IpAddrVersion::V6(v6_tuple)
    }

}
Olen opettelemassa Rustin alkeita ja nyt tuli tälläinen ongelma vastaan, että pitäisi tuple:sta saada purettua argumentit enum konstruktorille. Onko olemassa eleganttia tapaa purkaa v6_tuple argumenteiksi, joita V6 odottaa?
 
Liittynyt
16.11.2020
Viestejä
2 565
Tuli mieleen tuosta package-lock.json keskustelusta, että kun oon pidemmän aikaa hoitanut kaikenlaista infra- ja devops -hommaa bäkkärikoodailujen sivussa (Java-maailmassa) ja tuoreimmassa projektissa on fronttirepojakin matkassa, niin onko kokemuksia toimivasta haavoittuvuustarkistuksesta npm-paketeille, minkä sais kiinnitettyä CI:hin?

Mitä koitin aamulla asiaa tutkia, niin "npm audit" jollain sopivalla audit-levelillä hoitais noin niinku periaatteessa asian out of the box, mutta ei ilmeisesti sisällä minkäänlaista whitelistausta, mikä taas voi johtaa kaikenlaisiin ärsyttäviin blokkeihin CI:ssä, mille et voi itse mitään. Eikä tunnu oikein hyvältä ajatukselta se, että rakentaa ohituksia CI:hin. Rikkoo minusta, ainakin osittain, koko tarkistusten ideaa, ettei kukaan pääsis viemään rikkonaista kamaa ajoon. Vähintäänkin aiheuttaa ylimääräistä säätöä CI-jobien kanssa.

Maksullisista Snyk näytti lupaavalta, mutta voi olla kankeaa saada käyttöön. Sonarista taas en saanut tolkkua, saisko sen kautta tarkistetuksi nämät npm-paketit.
 
Viimeksi muokattu:
Liittynyt
17.10.2016
Viestejä
1 115
Koodi:
enum IpAddrVersion {
    V4(u8, u8, u8, u8),
    V6(u16, u16, u16, u16, u16, u16, u16, u16),
}
type IP = IpAddrVersion;

impl IpAddrVersion {
    fn is_valid_v6(&self) -> bool {
        match self {
            Self::V4(_,_,_,_) => false,
            Self::V6(..) => true,
        }
    }
   
    // TODO
    fn regex_match_v6() -> bool {false}
    fn to_string() {}
    fn to_string_compressed() {}

    fn from_string(input: &String) -> IpAddrVersion {
        let v6_tuple: (u16, u16, u16, u16, u16, u16, u16, u16) = (0,0,0,0,0,0,0,1);
        IpAddrVersion::V6(v6_tuple)
    }

}
Olen opettelemassa Rustin alkeita ja nyt tuli tälläinen ongelma vastaan, että pitäisi tuple:sta saada purettua argumentit enum konstruktorille. Onko olemassa eleganttia tapaa purkaa v6_tuple argumenteiksi, joita V6 odottaa?
Ei tule mieleen näppärää tapaa tuplella, mutta jos et ole erityisesti pakotettu sellaisiin niin eikö. esim array toimisi? Pikaisesti ylemmästä muokattuna:
Koodi:
enum IpAddrVersion {
    V4([u8; 4]),
    V6([u16; 8]),
}

impl IpAddrVersion {
    fn is_valid_v6(&self) -> bool {
        match self {
            Self::V4(..) => false,
            Self::V6(..) => true,
        }
    }
    
    // TODO
    fn regex_match_v6() -> bool {false}
    fn to_string() {}
    fn to_string_compressed() {}

    fn from_string(input: &str) -> IpAddrVersion {
        let v6_array = [0,0,0,0,0,0,0,1];
        IpAddrVersion::V6(v6_array)
    }

}
 
Liittynyt
17.10.2016
Viestejä
1 115
Rust ei ole vielä tuttu, mutta eikö tuota voi tehdä destrukturoinnoilla?
Voi toki, ja normaalisti varmasti ensimmäinen mitä tuossa tehtäisiin. Oletin, ehkäpä virheellisesti, että tämä oli jo tiedossa ja todettiin ei-elegantiksi koska sellaista oltiin vailla.
Koodi:
    fn from_string(input: &String) -> IpAddrVersion {
        let v6_tuple: (u16, u16, u16, u16, u16, u16, u16, u16) = (0,0,0,0,0,0,0,1);
        IpAddrVersion::V6(v6_tuple.0, v6_tuple.1, v6_tuple.2, v6_tuple.3, v6_tuple.4, v6_tuple.5, v6_tuple.6, v6_tuple.7)
    }
 
Liittynyt
05.02.2017
Viestejä
176
Voi toki, ja normaalisti varmasti ensimmäinen mitä tuossa tehtäisiin. Oletin, ehkäpä virheellisesti, että tämä oli jo tiedossa ja todettiin ei-elegantiksi koska sellaista oltiin vailla.
Koodi:
    fn from_string(input: &String) -> IpAddrVersion {
        let v6_tuple: (u16, u16, u16, u16, u16, u16, u16, u16) = (0,0,0,0,0,0,0,1);
        IpAddrVersion::V6(v6_tuple.0, v6_tuple.1, v6_tuple.2, v6_tuple.3, v6_tuple.4, v6_tuple.5, v6_tuple.6, v6_tuple.7)
    }
Kiitos molemmille vastauksista!

Jäin tosiaan ihmetteleen, olisiko rustissa pythonia vastaavaa argument unpacking ominaisuutta: Packing and Unpacking Arguments in Python - GeeksforGeeks

Ilmeisesti siis ei ole. Päädyin muuttamaan tuon arrayksi kuten ehdotit.
 
Liittynyt
05.02.2017
Viestejä
176
Rich (BB code):
use regex::Regex;
use std::{u8, u16};

enum IpAddrVersion {
    V4 {mask: u8, addr:[u8; 4]},
    V6 {mask: u8, addr:[u16; 8]},
}
type IP = IpAddrVersion;

impl IpAddrVersion {
    fn is_valid_v6(&self) -> bool {
        match self {
            Self::V4{..} => false,
            Self::V6{..} => true,
        }
    }
    
    // TODO
    fn regex_match_v6() -> bool {false}
    fn to_string(&self) -> String {
        match self {
            Self::V4{mask, addr} => {
                format!("{}.{}.{}.{}/{}", addr[0], addr[1], addr[2], addr[3], mask)
            },
            Self::V6{mask, addr} => {
                let mut ipv6 = String::new();
                for block in addr {
                    ipv6.push_str(&format!("{:x}", block));
                    ipv6.push_str(":");
                }
                ipv6.pop();
                ipv6.push_str("/");
                ipv6.push_str(&mask.to_string());
                return ipv6
            },
        }
    }

    fn to_string_compressed(&self) -> String {
        match self {
            Self::V4{mask, addr} => Self::to_string(&Self),
            Self::V6{mask, addr} => {
                let mut ipv6 = String::new();
                let mut null_block_pattern: (usize, usize) = (0,0); // (start, length)
                let mut null_block_pattern_record = null_block_pattern;
                
                // find the longest consecutive null pattern
                for (i, block) in addr.iter().enumerate() {
                    if block==0 {
                        if null_block_pattern.0 + null_block_pattern.1 == i{
                            null_block_pattern.1 +=1;
                        } else {
                            if null_block_pattern.1 > null_block_pattern_record.1 {
                                null_block_pattern_record = null_block_pattern;
                            }
                            null_block_pattern.0 = i;
                            null_block_pattern.1 = 1;
                        }
                    }
                }
                if null_block_pattern.1 > null_block_pattern_record.1 {
                    null_block_pattern = null_block_pattern_record;
                }
                for (i, block) in addr.iter().enumerate() {
                    if i >= null_block_pattern_record.1
                        && i <= null_block_pattern_record.0 + null_block_pattern_record.1 {
                        continue;
                    } else if i == null_block_pattern_record.0 + null_block_pattern_record.1 {
                        ipv6.push_str(":");
                    } else {
                        ipv6.push_str(&format!("{:x}", block));
                        ipv6.push_str(":");
                    }
                }
                ipv6.pop();
                ipv6.push_str("/");
                ipv6.push_str(&mask.to_string());
                return ipv6
            },
        }
    }

    fn from_string(input: &String) -> IpAddrVersion {
        let reg_v4 = Regex::new(r"\.").unwrap();
        if reg_v4.is_match(input) {
         //println!("Found IPV4 input string!"); // DEBUG
         let blocks = input.split('.');
         let blocks: Vec<&str> = blocks.collect();
         let mut v4_arr: [u8; 4] = [0;4];
         if blocks.len()==4 {
            for (i, val) in blocks.iter().enumerate() {
                let block_u8 = u8::from_str_radix(val, 10);
                match block_u8 {
                    Ok(v) => v4_arr = v,
                    Err(_) => panic!("Could not interpret {val} as an decimal number!"),
                }
            }
         }
        return IpAddrVersion::V4{mask: 0, addr: v4_arr}
        }

        let blocks = input.split(':');
        let blocks: Vec<&str> = blocks.collect();
        let mut v6_arr: [u16; 8] = [0;8];
        if blocks.len()==8 {
            for (i,val) in blocks.iter().enumerate() {
                let block_u16 = u16::from_str_radix(val, 16);
                match block_u16 {
                    Ok(v) => v6_arr = v,
                    Err(_) => panic!("Could not interpret {val} as an hexadecimal number!"),
                }
            }
        }
        return IpAddrVersion::V6{mask: 0, addr: v6_arr}
    }

}

fn main() {
    //let localhost = IpAddrVersion::V4(127, 0, 0, 1);
    let localhost_v6 = IP::from_string(&String::from("2001:0:0:0:0:dc00:0:6"));
    let localhost_v4 = IP::from_string(&String::from("127.0.0.1"));

    println!("{}", localhost_v4.to_string());
    println!("{}", localhost_v6.to_string());
    //print_ip_addr(&String::from("localhost"), &localhost_v6);
    //print_ip_addr(&String::from("localhost"), &localhost_v4); // verify localhost is still in scope!
    
}

fn print_ip_addr(host_name: &String, ip_addr: &IpAddrVersion) {
    
    println!("Host: {} IP: {}",  host_name, match ip_addr {
        IP::V6{mask: m, addr: arr} => format!("{:?}/{}", arr, m),
        IP::V4{mask: m, addr: [a,b,c,d]} => format!("{}.{}.{}.{}/{}",
                                              a.to_string(), b.to_string(), c.to_string(), d.to_string(), m )
        }
    );
}



Olen jatkanut koodiharjoitustani Rustilla ja taas muutama aika lähtötason ongelma, jotka korostettu oranssilla. Miten tuo self passataan enumin metodilta toiselle? Ja if vertailu tuottaa seuraavan virheen: can't compare `&u16` with `{integer}` - mikä on oikea tapa korjata tämä?

Alkaa olemaan taas pää niin jumissa, ettei aukene itsestään :grumpy:
 
Liittynyt
19.10.2016
Viestejä
1 560
Rich (BB code):
use regex::Regex;
use std::{u8, u16};

enum IpAddrVersion {
    V4 {mask: u8, addr:[u8; 4]},
    V6 {mask: u8, addr:[u16; 8]},
}
type IP = IpAddrVersion;

impl IpAddrVersion {
    fn is_valid_v6(&self) -> bool {
        match self {
            Self::V4{..} => false,
            Self::V6{..} => true,
        }
    }
   
    // TODO
    fn regex_match_v6() -> bool {false}
    fn to_string(&self) -> String {
        match self {
            Self::V4{mask, addr} => {
                format!("{}.{}.{}.{}/{}", addr[0], addr[1], addr[2], addr[3], mask)
            },
            Self::V6{mask, addr} => {
                let mut ipv6 = String::new();
                for block in addr {
                    ipv6.push_str(&format!("{:x}", block));
                    ipv6.push_str(":");
                }
                ipv6.pop();
                ipv6.push_str("/");
                ipv6.push_str(&mask.to_string());
                return ipv6
            },
        }
    }

    fn to_string_compressed(&self) -> String {
        match self {
            Self::V4{mask, addr} => Self::to_string(&Self),
            Self::V6{mask, addr} => {
                let mut ipv6 = String::new();
                let mut null_block_pattern: (usize, usize) = (0,0); // (start, length)
                let mut null_block_pattern_record = null_block_pattern;
               
                // find the longest consecutive null pattern
                for (i, block) in addr.iter().enumerate() {
                    if block==0 {
                        if null_block_pattern.0 + null_block_pattern.1 == i{
                            null_block_pattern.1 +=1;
                        } else {
                            if null_block_pattern.1 > null_block_pattern_record.1 {
                                null_block_pattern_record = null_block_pattern;
                            }
                            null_block_pattern.0 = i;
                            null_block_pattern.1 = 1;
                        }
                    }
                }
                if null_block_pattern.1 > null_block_pattern_record.1 {
                    null_block_pattern = null_block_pattern_record;
                }
                for (i, block) in addr.iter().enumerate() {
                    if i >= null_block_pattern_record.1
                        && i <= null_block_pattern_record.0 + null_block_pattern_record.1 {
                        continue;
                    } else if i == null_block_pattern_record.0 + null_block_pattern_record.1 {
                        ipv6.push_str(":");
                    } else {
                        ipv6.push_str(&format!("{:x}", block));
                        ipv6.push_str(":");
                    }
                }
                ipv6.pop();
                ipv6.push_str("/");
                ipv6.push_str(&mask.to_string());
                return ipv6
            },
        }
    }

    fn from_string(input: &String) -> IpAddrVersion {
        let reg_v4 = Regex::new(r"\.").unwrap();
        if reg_v4.is_match(input) {
         //println!("Found IPV4 input string!"); // DEBUG
         let blocks = input.split('.');
         let blocks: Vec<&str> = blocks.collect();
         let mut v4_arr: [u8; 4] = [0;4];
         if blocks.len()==4 {
            for (i, val) in blocks.iter().enumerate() {
                let block_u8 = u8::from_str_radix(val, 10);
                match block_u8 {
                    Ok(v) => v4_arr = v,
                    Err(_) => panic!("Could not interpret {val} as an decimal number!"),
                }
            }
         }
        return IpAddrVersion::V4{mask: 0, addr: v4_arr}
        }

        let blocks = input.split(':');
        let blocks: Vec<&str> = blocks.collect();
        let mut v6_arr: [u16; 8] = [0;8];
        if blocks.len()==8 {
            for (i,val) in blocks.iter().enumerate() {
                let block_u16 = u16::from_str_radix(val, 16);
                match block_u16 {
                    Ok(v) => v6_arr = v,
                    Err(_) => panic!("Could not interpret {val} as an hexadecimal number!"),
                }
            }
        }
        return IpAddrVersion::V6{mask: 0, addr: v6_arr}
    }

}

fn main() {
    //let localhost = IpAddrVersion::V4(127, 0, 0, 1);
    let localhost_v6 = IP::from_string(&String::from("2001:0:0:0:0:dc00:0:6"));
    let localhost_v4 = IP::from_string(&String::from("127.0.0.1"));

    println!("{}", localhost_v4.to_string());
    println!("{}", localhost_v6.to_string());
    //print_ip_addr(&String::from("localhost"), &localhost_v6);
    //print_ip_addr(&String::from("localhost"), &localhost_v4); // verify localhost is still in scope!
    
}

fn print_ip_addr(host_name: &String, ip_addr: &IpAddrVersion) {
    
    println!("Host: {} IP: {}",  host_name, match ip_addr {
        IP::V6{mask: m, addr: arr} => format!("{:?}/{}", arr, m),
        IP::V4{mask: m, addr: [a,b,c,d]} => format!("{}.{}.{}.{}/{}",
                                              a.to_string(), b.to_string(), c.to_string(), d.to_string(), m )
        }
    );
}

Olen jatkanut koodiharjoitustani Rustilla ja taas muutama aika lähtötason ongelma, jotka korostettu oranssilla. Miten tuo self passataan enumin metodilta toiselle? Ja if vertailu tuottaa seuraavan virheen: can't compare `&u16` with `{integer}` - mikä on oikea tapa korjata tämä?

Alkaa olemaan taas pää niin jumissa, ettei aukene itsestään :grumpy:
to_string-ongelma ratkeaa varmaan sanomalla yksinkertaisesti self.to_string(). Jälkimmäisestä en osaa sanoa valmista ratkaisua työntämättä koko höskää kääntäjälle ja yrittämällä siitä, mutta block on nyt nähtävästi &u16, kun taas 0 on jokin epämääräinen luku. Saattaisi lähteä toimimaan joko sanomalla *block == 0 tai kenties block == (0 as u16).
 
Liittynyt
05.02.2017
Viestejä
176
to_string-ongelma ratkeaa varmaan sanomalla yksinkertaisesti self.to_string(). Jälkimmäisestä en osaa sanoa valmista ratkaisua työntämättä koko höskää kääntäjälle ja yrittämällä siitä, mutta block on nyt nähtävästi &u16, kun taas 0 on jokin epämääräinen luku. Saattaisi lähteä toimimaan joko sanomalla *block == 0 tai kenties block == (0 as u16).
Tällähän se lähti toimiin, kiitos :tup:
 
Liittynyt
04.03.2017
Viestejä
282
React-osaamisessani on näköjään suuria aukkoja. Käytän react-queryä ja sain ajatuksen yleisestä wrapperistä joka hoitaisi loading/error yms. tilojen esittämisen:
Koodi:
interface QueryResultProps {
  result: UseQueryResult;
  children: React.ReactNode;
}

const QueryResult: React.FC<QueryResultProps> = ({ result, children }) => {
  if (result.isLoading)
    return <p>Loading...</p>;

  if (result.isError)
    return <p>{`Error: ${result.error}`}</p>;

  if (result.isSuccess)
    return <Fragment>{children}</Fragment>;

  return null;
};
Ja voisin käyttää sitä tähän tapaan:
Koodi:
const items = useQuery('items', getItems);

<QueryResult result={items}>
    <ul>
        {items.data.map((item: Item) => <li>{item.title}</li>)}
    </ul>
</QueryResult>
Mutta tuosta seuraa virhe "Uncaught TypeError: Cannot read properties of undefined (reading 'items')" joka indikoisi sitä että childrenit rendataan/mountataan riippumatta parentin tilasta? Eli nyt joudun lisäämään tuonne childreniin ehdollisen renderöinnin items.isSuccessin kanssa ja juuri siitä haluaisin eroon. Olenko ymmärtänyt jotain pahasti väärin ja miten tuollaisen kuvatunlaisen mekanismin toteutus onnistuisi Reactissa?
 
Liittynyt
09.03.2017
Viestejä
37
Moikka! Todnäk todella yksinkertainen ongelma Reactissa johon aloittelija ei saa ratkaisua aikaan.
Kuten alempana näkyy minulta löytyy taulukko jossa on muutama tekstinpätkä ja alempana luon taulukon jokaiselle viestille omat tekstiboksin (kuvittele vaikka chat viesti).
Ajattelin huvikseen kokeilla korvata nuo taulukon viestit twitchin chat viesteillä. Netistä löytyi tuommoinen tmi.js paketti jonka avulla voi helposti lukea chatin viestejä. Tällä hetkellä tuo toimii oikein hyvin ja tulostaa selaimen konsoliin valitsemani kanavan viestejä.
Oma ratkaisuni asiaan oli, työntää jokainen viesti aina tohon text taulukkoon, mutta ongelmaksi muodostui jostakin syystä että viestit tulivat moneen kertaan ruudulle ( käytin tässä useStatea ja epäilen että liittyy jotenkin reactin renderöintiin, mitä en vielä täysin ymmärrä).
Edellä mainittu tapa on todennäköisesti aivan turhan hankala ja voisin kuvitella että tämän voisi toteuttaa helpommin, luomalla suoraan uusi textbox komponentti viestin tullessa mutta googlettelu ei tuottanut tulosta.

TLDR; Tavoitteena luoda aina uusi <TextBox /> kun uusi viesti saapuu, mutta miten?
En kaipaa suoraa vastausta, mutta enemmänkin pientä tökkäystä oikeaan suuntaan
Koodi:
import TextBox from './TextBox';

const tmi = require('tmi.js');
const client = new tmi.Client({
    channels: [ 'MrSyS0p' ] //Tähän mikä tahansa "aktiivinen" kanava
});
client.connect();
console.clear();
client.on('message', (channel, tags, message, self) => {
    // "Alca: Hello, World!"
    console.log(`${tags['display-name']}: ${message}`);
});


function Container() {
    const text = [
        "Viesti1",
        "Viesti2",
        "Viesti3",
        "Viesti4",
        "Viesti5"
    ]

    return (
        <div className='container'>
            {
            text.map((item, index) => {
                return <TextBox key={index} Msg={item}/>
            })
            }          
        </div>
    );
}

export default Container;
e:siistin hieman koodia
 
Liittynyt
18.10.2016
Viestejä
107
React-osaamisessani on näköjään suuria aukkoja. Käytän react-queryä ja sain ajatuksen yleisestä wrapperistä joka hoitaisi loading/error yms. tilojen esittämisen:
Koodi:
interface QueryResultProps {
  result: UseQueryResult;
  children: React.ReactNode;
}

const QueryResult: React.FC<QueryResultProps> = ({ result, children }) => {
  if (result.isLoading)
    return <p>Loading...</p>;

  if (result.isError)
    return <p>{`Error: ${result.error}`}</p>;

  if (result.isSuccess)
    return <Fragment>{children}</Fragment>;

  return null;
};
Ja voisin käyttää sitä tähän tapaan:
Koodi:
const items = useQuery('items', getItems);

<QueryResult result={items}>
    <ul>
        {items.data.map((item: Item) => <li>{item.title}</li>)}
    </ul>
</QueryResult>
Mutta tuosta seuraa virhe "Uncaught TypeError: Cannot read properties of undefined (reading 'items')" joka indikoisi sitä että childrenit rendataan/mountataan riippumatta parentin tilasta? Eli nyt joudun lisäämään tuonne childreniin ehdollisen renderöinnin items.isSuccessin kanssa ja juuri siitä haluaisin eroon. Olenko ymmärtänyt jotain pahasti väärin ja miten tuollaisen kuvatunlaisen mekanismin toteutus onnistuisi Reactissa?
Toi ongelma johtuu siitä että React yrittää piirtää tuloksia silloin kun QueryResult komponentille annetaan propsit ja kun tarkistus lataukselle/virheille tehdään vasta QueryResult komponentissä niin tulee virhe. Asiaa voi demonstroida console.loggaamalla props.childern QueryResult komponentissä ekana, huomaat että se on eka tyhjä/false ja datan ladattua se loggaantuu uudestaan ja data näkyy. Mitä yleensä nähnyt queryä käytettävän niin on ollut lataamiselle ja errorille omat komponentit ja vaan laitettu ne jokasen paikkaan erikseen, tyyliin:
Koodi:
if (isLoading) return <Loading />
if (error) return <Error error={error} />
if (data.length === 0) <NoResults />
Mutta jos alkuperäisellä idealla tekisin jotenkin tälleen:
Koodi:
const QueryResult: React.FC<QueryResultProps> = ({ result }) => {
  if (result.isLoading) return <p>Loading...</p>;
  if (result.isError) return <p>{`Error: ${result.error}`}</p>;
  return null;
};

// käyttö:
const items = useQuery('items', getItems);

if (!items.isSuccess)  return <QueryResult result={items} />

return (
    <ul>
        {items.data.map((item: Item) => <li>{item.title}</li>)}
    </ul>
)
(en testannut toimiiko koodi mutta idea on tuo)
 
Liittynyt
04.03.2017
Viestejä
282
Mitä yleensä nähnyt queryä käytettävän niin on ollut lataamiselle ja errorille omat komponentit ja vaan laitettu ne jokasen paikkaan erikseen, tyyliin:
Koodi:
if (isLoading) return <Loading />
if (error) return <Error error={error} />
if (data.length === 0) <NoResults />
Joo, noin react-queryä olen normaalisti käyttänyt, mutta kun lähes samaa toistaa joka näkymässä useampaan kertaan niin tuli mieleen olisiko abstraktimpaa tapaa toteuttaa sama.

Kun asiaa pohdin niin jos annan sisällön komponentille childrenin sijaan funktio-parametrina niin sitten se toimii koska evaluointi tapahtuu vasta funktiota kutsuttaessa:
Koodi:
const items = useQuery('items', getItems);

<QueryResult query={items} result={(data: Item[]) =>
    <ul>
        {data.map((item: Item) => <li>{item.title}</li>)}
    </ul>
}/>
 
Liittynyt
03.07.2018
Viestejä
347
Ideoin tässä S3 / google bucketin käyttöä, mutta niissähän tiedostot on jaettavissa suoralla linkillä kenelle vaan.
Ja jos taas lukee palvelinpuolen ohjelmalla tiedoston bucketista käyttäjälle niin tämähän kuluttaa sitten taas kallista app-serverin kaistaa.
Miten tämä on yleensä ratkaistu ? Voiko bucketista pyytää kertakäyttölinkin tms. linkin mikä toimisi vaikka 24h ?
 
Liittynyt
03.07.2018
Viestejä
347
Ja toinen kysymys, ei ole hirveästi ainakaan hyvää kokemusta dockerista tms, mutta voisiko sitä tai kubernetsiä käyttää siihen että teen lataan jostain valmiin python3 imagen, laitan siihen cronilla oman ohjelman pyörimään ajastetusti ja sitten ostan jostain palvelimen johon voi ladata tuon imagen suoraan ? ja tarvittaessa siis saisi näin saman ohjelman pyörimään yhtä aikaa monella eri koneella helposti? Ohjelma ei sisällä inbound-liikennettä joten http-palvelinta ei tarvitse olla. Taka-ajatukseni on ettei siis tarvitisi manuaalisesti ylläpitää ja päivitellä mitään virtuaalilinuxeja missään hefnerillä... ja mahdollisesti saisi vielä kaikki ympäristöt päivittymään kunhan pushaa uuden koodin bitbuckettiin...
 
Liittynyt
04.03.2017
Viestejä
282
En tunne S3:a tarkemmin, mutta noin se toimii esim Azure Blobeilla. Eli blokataan anonyymi pääsy buckettiin/containeriin ja applikaatiossa sopivalla kirjastolla generoidaan käyttäjälle SAS-tokenin sisältävä urli jolla tiedoston voi ladata määriteltynä aikavälinä. SAS-tokeneilla voi yleensä myöntää muitakin kuin pelkkiä lukuoikeuksia, joten pitää olla tarkkana ettet salli samalla esim. tiedoston tai koko containerin muokkaamista.
 
Liittynyt
17.10.2016
Viestejä
14 550
Ideoin tässä S3 / google bucketin käyttöä, mutta niissähän tiedostot on jaettavissa suoralla linkillä kenelle vaan.
Ja jos taas lukee palvelinpuolen ohjelmalla tiedoston bucketista käyttäjälle niin tämähän kuluttaa sitten taas kallista app-serverin kaistaa.
Miten tämä on yleensä ratkaistu ? Voiko bucketista pyytää kertakäyttölinkin tms. linkin mikä toimisi vaikka 24h ?
AWS:ssä s3:n objekteja (tiedostoja) voi jakaa ns. presigned URL:n avulla niin, että se objekti on vain määrätyn ajan luettavissa. Mutta ehkä olisi parempi, jos kerrot mitä yrität tehdä, niin sitten on helpompi miettiä, miten se kannattaisi tehdä. Eli millaista kamaa s3:een tallentaisit, miten ja kuka niitä saisi lukea ja kuinka usein?
 
Liittynyt
17.10.2016
Viestejä
14 550
Ja toinen kysymys, ei ole hirveästi ainakaan hyvää kokemusta dockerista tms, mutta voisiko sitä tai kubernetsiä käyttää siihen että teen lataan jostain valmiin python3 imagen, laitan siihen cronilla oman ohjelman pyörimään ajastetusti ja sitten ostan jostain palvelimen johon voi ladata tuon imagen suoraan ? ja tarvittaessa siis saisi näin saman ohjelman pyörimään yhtä aikaa monella eri koneella helposti? Ohjelma ei sisällä inbound-liikennettä joten http-palvelinta ei tarvitse olla. Taka-ajatukseni on ettei siis tarvitisi manuaalisesti ylläpitää ja päivitellä mitään virtuaalilinuxeja missään hefnerillä... ja mahdollisesti saisi vielä kaikki ympäristöt päivittymään kunhan pushaa uuden koodin bitbuckettiin...
Kubernetesia en tunne. Mutta varmaan kaikissa pilvipalveluissa voit ajaa Pythonia ns. serverlessinä. AWS:ssä esim. voit laittaa lambdan ajamaan sitä Pythonia halutulla ajastuksella. Joko suoraan Pythonia tai dockerin kautta. Kummassakin omat hyötynsä ja haittansa. Ja yleensäkin on aina kiva, jos ei tarvise servereitä ylläpitää.
 
Liittynyt
16.11.2020
Viestejä
2 565
Joo, joku API Gateway + Lambda lienee oikea teknologiavalinta AWS:ssä, jos tarvii saada pienemmällä vaivalla jotain kevyttä palvelua ajoon ja ei halua ylläpitää palvelimia. Pitäs skaalautua ihan riittävästi kaikkeen tavanomaiseen tarpeeseen. muoks. toki, niin kuin jo sanottukin, tää on vähän tällaista heittelyä, kun ei tiedä todellista tarvetta.

ECS-palvelu sit toinen, minne voi pukata kontti-imagea ajoon ja kun ajaa Fargatena, niin ei tarvitse sielläkään palvelimia nostella, mutta tuohon sais sitten väsätä VPC:n, säännöt verkkoliikenteelle, loadbalancerin ja kaikkea sellaista, mihin menee äkkiä useampi päivä aikaa ja ihmettelyä, jos ei oo tuttua. Tulee myös huomattavasti kalliimmaksi kuin tuo eka vaihtoehto.

Kubernetes (AWS:ssä EKS-palvelu) kaikkein raskain, vaatii osaamista ja säännöllistä ylläpitoa versionnostoineen. Ei kannata minusta miettiä, jos ei ole oikeasti tarvetta raskaammalle konttiorkestraatiolle. Pesee kyllä raskaammassa käytössä sit minun makuuni ECS:n osapuilleen kaikessa, jos hallintaan ja ylläpitoon löytyy vaan aikaa ja osaamista.
 
Viimeksi muokattu:
Liittynyt
09.02.2019
Viestejä
78
Miten lasketaan pisteen ja kolmion välinen etäisyys? Pitäsi löytää pisteelle lähin kolmio, kolmoita voi olla tuhansia. Piste ei ole minkään kolmion päällä.
 
Liittynyt
18.10.2016
Viestejä
107
Miten lasketaan pisteen ja kolmion välinen etäisyys? Pitäsi löytää pisteelle lähin kolmio, kolmoita voi olla tuhansia. Piste ei ole minkään kolmion päällä.
Kuulostaa koulutehtävältä. Itse lähtisin kahdella sisäkkäisellä loopilla missä missä ulompi kasvattaa ympyrän sädettä ja sisempi käy kulman suuruuksia välilä 0-2π. Sitten tarkistaa osuuko piste kolmion sisälle. Tuosta sitten vaan säätää riittävä tarkkuus, useamman samalla etäisyydellä olevan kolmion hallinta ja mukava ohjelmointikieli.
 
Liittynyt
09.02.2019
Viestejä
78
Kuulostaa koulutehtävältä. Itse lähtisin kahdella sisäkkäisellä loopilla missä missä ulompi kasvattaa ympyrän sädettä ja sisempi käy kulman suuruuksia välilä 0-2π. Sitten tarkistaa osuuko piste kolmion sisälle. Tuosta sitten vaan säätää riittävä tarkkuus, useamman samalla etäisyydellä olevan kolmion hallinta ja mukava ohjelmointikieli.
Ei ole koulutehtävä, eikä itseasiassia ongelmana loopit yms. vaan puhdas matematiikka, että miten valitaan pisteelle lähin kolmio.
Nyt en ihan ymmärtänyt tuota ympyrän säde hommaan. Niinkö että pisteelle annetaan jokin säde, jotta saadaan selville kolmion sivu, jonka se lähimpänä leikkaa?
Nyt yritän etsiä lähintä kolmiota selvittämällä jokaisen kolmion sivun ja pisteen välisen suorakulmaisen etäisyyden ja valitsen kolmion jossa välimatka on lyhin. Tämä toimii n90% tapauksista...
 
Liittynyt
16.11.2020
Viestejä
2 565
^ niin eikö tuossa ollu vaan ideana se, että lähimmän kolmion lähin piste tulee vastaan r-säteisen ympyrän kehällä (tutkittava piste on ympyrän keskipiste), jos lähdet kasvattamaan ympyrän sädettä r ja tutkit pisteitä ympyrän kehällä.

Tai noin minä tuota ite mietin, kun satuin huomaamaan.
 
Toggle Sidebar

Statistiikka

Viestiketjut
237 422
Viestejä
4 160 699
Jäsenet
70 408
Uusin jäsen
allun90

Hinta.fi

Ylös Bottom