Pieniä kysymyksiä ohjelmoinnista

Gigatavun kokoisesta tiedostosta on hidas hakea yhtä tiettyä asiaa. Tuhannen eri tiedoston lukeminen on hidasta. Jos kaikki luetaan aina niin yks tiedosto kelpaa. Jos taas haluat aina lukea vain yhden tai vain pari tuhansista olioista niin tee niille omat tiedostot. Oma mielipide.
 
On varmaan termistökin hukassa, mutta idea on tallentaa listat olioista a,b ja c!
Miten tuo olisi kaikista järkevin hakea takaisin nimellä a b tai c? Luomalla noista yksi tiedosto ja käydä läpi koko data ja poimia sieltä haluttu lista, vai luoda listoista omat tiedostot ja hakea vain halutun listan tiedosto?

Gigatavun kokoisesta tiedostosta on hidas hakea yhtä tiettyä asiaa. Tuhannen eri tiedoston lukeminen on hidasta. Jos kaikki luetaan aina niin yks tiedosto kelpaa. Jos taas haluat aina lukea vain yhden tai vain pari tuhansista olioista niin tee niille omat tiedostot. Oma mielipide.

Justiinsa niinkun TheMeII ilmi toi.
Eli riippuu ainakin seuraavista seikoista:
- Olioiden kokoluokasta
- Olioiden määrästä / lista
- Listojen määrästä
- Käsittelytiheydestä ( puljataanko tiedostosta aina yks otus sieltä täältä vai koko lista yhdellä kertaa )

Jos ajatuksena on ikäänkuin kertaluontoisesti lukea tiedostosta datat sovellukseen käynnistettäessä ja sitten tallennettaessa/lopetettaessa kirjoittaa takasisin niin varmaan yksi iso tiedosto ajaa asian. Jos on jotain loogisia kokonaisuuksia joita käsitellään erikseen, esim yhden listan olioita kerrallan niin toki voi olla selkämpää käsitellä tiedosto kerrallaan.

Jos tietomassa on oikeasti sen kokoinen, että tämäntyyppiset kysymykset alkavat merkitä, niin yksi vaihtoehto on käyttää jotain sulautettua/tiedostotietokantaa/tms esim SQLlite ( SQLite: Single File Database ) tai HSQLDB ( HSQLDB )

Joka tapauksessa: Todennäköisesti yliajattelet asiaa nyt reilusti, todennäköisesti asialla ei ole niin suurta merkitystä mitä luulet - kunhan päätös johon päädyt ( ks. Oma mielipide ) on itsellesi/kanssakehittäjille/käyttäjille(?) selkeä ja looginen niin se ajanee asian. Ja voithan toteuttaa asian vaikka yhteen tiedostoon kirjoittamalla ja koittaa toteuttaessa pitää mielessä huolesi ja tehdä rakenteen niin että tarvittaessa pystyt helposti muuttamaan tämän tyylistä toiseen.
 
Justiinsa niinkun TheMeII ilmi toi.
Eli riippuu ainakin seuraavista seikoista:
- Olioiden kokoluokasta
- Olioiden määrästä / lista
- Listojen määrästä
- Käsittelytiheydestä ( puljataanko tiedostosta aina yks otus sieltä täältä vai koko lista yhdellä kertaa )

Jos ajatuksena on ikäänkuin kertaluontoisesti lukea tiedostosta datat sovellukseen käynnistettäessä ja sitten tallennettaessa/lopetettaessa kirjoittaa takasisin niin varmaan yksi iso tiedosto ajaa asian. Jos on jotain loogisia kokonaisuuksia joita käsitellään erikseen, esim yhden listan olioita kerrallan niin toki voi olla selkämpää käsitellä tiedosto kerrallaan.

Jos tietomassa on oikeasti sen kokoinen, että tämäntyyppiset kysymykset alkavat merkitä, niin yksi vaihtoehto on käyttää jotain sulautettua/tiedostotietokantaa/tms esim SQLlite ( SQLite: Single File Database ) tai HSQLDB ( HSQLDB )

Joka tapauksessa: Todennäköisesti yliajattelet asiaa nyt reilusti, todennäköisesti asialla ei ole niin suurta merkitystä mitä luulet - kunhan päätös johon päädyt ( ks. Oma mielipide ) on itsellesi/kanssakehittäjille/käyttäjille(?) selkeä ja looginen niin se ajanee asian. Ja voithan toteuttaa asian vaikka yhteen tiedostoon kirjoittamalla ja koittaa toteuttaessa pitää mielessä huolesi ja tehdä rakenteen niin että tarvittaessa pystyt helposti muuttamaan tämän tyylistä toiseen.


Kiitoksia! Tämä nyt ei ole mikään työnalla oleva asia vaan lähinnä mietin, että onko tähän joku yleisesti hyväksytty tapa taikka sääntö jota käytetään.
 
Mikähän olisi omassa tapauksessani tehokkain tapa tallentaa 512 byteä dataa ja tarvittaessa ladata ne takaisin? Kielenä on Python3 jota ajetaan RasPi:n päällä. Tuo data olisi DMX512-dataa eli valaistusohjausdataa, siitä tuo 512 tavua. Kokonaisuutena homma siis toimii niin että nettisivu lähettää kourallisen parametreja python-kikkareelle tyyliin 1,8,9,255,255,255,0,0,0,0,1 eli tuossa rimpsussa on DMX-universe, montako kanavaa tulee dataa ja mistä kanavasta data alkaa ja perässä data.

Lähinnä ajattelin että kun (itsetehty) nettisivu lähettää tuollaisia rimpsuja jotka käsittelen pythonilla joka taas lähettää lopputuloksen OLA:lle (Open Lighting Architecture) joka ohjaa PathPortin Ethernet-DMX -siltaa niin miten tuota dataa tallentaisi tuossa välissä kätevimmin? Data tulee valaisinkohtaisesti ja ola haluaa koko dmx-kanavakokonaisuuden datan kerrallaan joten ajattelin että python-kikkare tallentaisi aina lähetetyn datan talteen ja kun annetaan uusi käsky jollekin lampulle niin ladattaisiin nykytilanne tiedostosta takaisin muistiin, muokataan siihen uudet valaistusohjeet, tallennettaisiin tilanne ja lähetettäisiin data dmx-softalle. Tuo pythoni ei siis pyöri koko ajan taustalla vaan sitä kutsutaan vain silloin kun valaistusasetuksissa tapahtuu muutoksia.

Mikäs tässä olisi järkevin tapa tallennella ja latailla tuota dataa? Joudun siis koostamaan tuosta datasta pitkän stringin kun lähetän sen komentoriviparametrina ola:lle. Mietin että periaatteessahan tuon voisi suoraan sylkäistä tiedostoon tavuina binäärisenä, toisaalta Picklellä saisi sen näppärästi jos puörittelen dataa vaikka listana ja kolmantena vaihtoehtona vieläpä ihan tallentaisin stringinpätkinä.

Lähinnä kiinnostaisi mikä on nopein tapa pyöritellä tuota dataa, kuitenkin haluaisi että vasteaika nettisovelluksella olisi mahdollisimman lyhyt. Tietty jos tuon pythonin saisi jotenkin pyörimään koko ajan taustalla ja sille saisi kivasti parametreja lennosta annettua niin vasteajat varmaan paranisivat huomattavasti kun ei tarvitsisi odotella pythonin käynnistystä joka komennolla.
 
Lähinnä kiinnostaisi mikä on nopein tapa pyöritellä tuota dataa, kuitenkin haluaisi että vasteaika nettisovelluksella olisi mahdollisimman lyhyt.

Lähetä koko 512 tavua vaan kerralla nettisivuilta raspille, mikä välittää sen suoraan eteenpäin, ei tuon datamäärän pitäisi hirveän viiveenä näkyä, kun tuon valaisin systeemin protocolla toimii 250kbs nopeudella kuitenkin, siitä voit laskea monta sekuntia menee tuo lähettää. Tietty voit tuon tallentaa siellä raspilla, mutta onko siitä mitään iloa on asia erikseen.

E: itse aloittaisin siitä että se python kikkare pyörii kokoajan taustalla, tuon datamäärän liikuttelun ja käsittelyn ei luulisi vievän hirveästi aikaa.
 
Viimeksi muokattu:
Tuo nettisivu itsessäänkin pyörii samassa raspissa kuin tuo python. Ja tuohon nettisivuun on (ainakin mun taidoilla) huomattavasti hankalampi viritellä koko datarimpsun lähetystä kun vanhat muiden kanavien arvot pitäisi pitää tallessa ja vieläpä niin että eri laitteilla tehdyissä säädöissä muiden kanavien asetukset säilyisivät.

Itseasiassa nyt kun on nukkunut yön yli ja muutenkin miettinyt asiaa, tuli mieleen jo monta muutakin huomioon otettavaa asiaa, kuten se ettei kirjoitetakaan tuota dataa ainakaan raspin SD-kortille jaan mieluummin vaikka ramdiskille. Pitääkin ruveta tutkimaan miten saisin tuon pythonin toimimaan koko ajan taustalla, se ratkaisisi samalla pari muutakin juttua...
 
Tuo nettisivu itsessäänkin pyörii samassa raspissa kuin tuo python. Ja tuohon nettisivuun on (ainakin mun taidoilla) huomattavasti hankalampi viritellä koko datarimpsun lähetystä kun vanhat muiden kanavien arvot pitäisi pitää tallessa ja vieläpä niin että eri laitteilla tehdyissä säädöissä muiden kanavien asetukset säilyisivät.

Itseasiassa nyt kun on nukkunut yön yli ja muutenkin miettinyt asiaa, tuli mieleen jo monta muutakin huomioon otettavaa asiaa, kuten se ettei kirjoitetakaan tuota dataa ainakaan raspin SD-kortille jaan mieluummin vaikka ramdiskille. Pitääkin ruveta tutkimaan miten saisin tuon pythonin toimimaan koko ajan taustalla, se ratkaisisi samalla pari muutakin juttua...
Tee siitä pythonista servu joka aina saadessaan uutta dataa kasaa uuden paketin ja lähettää eteenpäin ja tallentaa ramdiskille. lisäksi vaikka croni kopioimaan 6-12h välein sd:lle jos haluaa datat pysyvämmin muistiin. Tuollain tulee kuitenkin vuodessa vain reilu 1-2000 kirjoitusta.
 
Yhtäkkiä tuli sellainen visio että tuohon varmaan voisi käyttää pythonin simpleHTTPserveriä. Sitä ainakin pikaisen googlettelun perusteella voisi ilmeisesti komennella ihan tavallisilla nettisivun linkeillä jonka sisällön perusteella serveri sitten tekee mitä halutaan. Jos tuo toimii jotenkin noin kuin kuvittelen niin tästä eteenpäin tuo ei ole enää kuin pari kuppia kahvia, pari olutta ja reilusti koodaamista. Vai olenko tämän asian kanssa ihan hakoteillä?

Tuo DMX-data ei ole mitään niin kriittistä että sitä kannattaisi pysyvästi tallentaa, kunhan pysyy jossakin muistissa sen verran että eri selaimia käytettäessä tila pysyisi tiedossa. Esim sähkökatkon tai muun vastaavan jälkeen joka tapauksessa lamput sammuvat ja niihin pitää ajaa uudestaan data sisään eli sen suhteen ei ole ongelmaa.

Itseasiassa jost tuo toimii noin niin voisikin koko backend-purkan koodata pythonilla, tällä hetkellä tuota kotiautomaatio/hallintajärjestelmää jossa tuo DMX-valaistusohjauskin on hoitelee sekalainen määrä shelliskriptejä, pythonin riekaleita, perliä ja ties mitä. Tuosta saisi yhden selkeän kokonaisuuden eikä jonkun pikkuasian muuttaminen vaatisi 100 eri fileen käpistelyä.

edit:
Kiitoksia JoniS ja TheMell, tuo serveri-idea ilmeisesti toimii tuossa mun tapauksessa just niin kuin haluankin, potkaisitte mua oikeaan suuntaan. Ensimmäinen hyvin riisuttu testiprotokoodi on kasassa ja saan siitä kivasti ulos sille lähetetyn stringin ja vasteaika on ihan eri luokkaa kuin vanhaan tapaan että python käynnistetään joka kerta uusiksi. Nyt viiveenä tulee olemaan käytännössä enää nettiyhteyden nopeus ja OLA-serverin oma hitaus lähettää DMX-data eth-dmx -palikalle, itse python-skripti ei käytännössä enää aiheuta viivettä hommaan.

Samaan serverityyliin pitää kirjoittaa nettiradiosoittimen ohjauksen koodikin uusiksi, siinä pahimpana ongelmana on ollut pitkä viive kun joka kerta kun käyttöliittymästä painaa nappia niin skripti kirjautuu soittimeen ja vasta sitten saa lähetettyä komentoja ja tuo kirjautuminen ottaa aikaa reilun sekunnin. Tuolla serverityylillä voi pitää session koko ajan auki ja komennot menevät läpi silmänräpäyksessä.

Nyt vaan kaljaa koneeseen ja koodia vääntämään...
 
Viimeksi muokattu:
hei! mistä kannattaa aloitta kun haluaisi tehdä webbi sivulle lämpötilakäyrän jota voisi zoomata ja hiiren päälle vieminen kertoisi ajan ja lämmön?

lämpötila dataa kerätään lämmityskattilan ohjaimesta raspberry pi:n ja RRDtoolin avulla tällä hetkeellä
 
hei! mistä kannattaa aloitta kun haluaisi tehdä webbi sivulle lämpötilakäyrän jota voisi zoomata ja hiiren päälle vieminen kertoisi ajan ja lämmön?

lämpötila dataa kerätään lämmityskattilan ohjaimesta raspberry pi:n ja RRDtoolin avulla tällä hetkeellä

Oletan että sulla on pi:ssä HTTP-palvelinohjelma, esim Apache?


Google Charts on tällaiseen puuhasteluun varsin hyvä. Valmiita tauluja löytyy yllinkyllin ja evät maksa mittään.
Line Chart | Charts | Google Developers
RRDtooli:a en tunne, mutta jos tuo talleentaa datan pi:lle helposti luettavaan tiedostoon, niin PHP on varmaan simppeli tapa siirtää data selameen/tauluun.

Sitte osu joku tällen node.js /node_rrd silmään.
rrdtools
 
Viimeksi muokattu:
hei! mistä kannattaa aloitta kun haluaisi tehdä webbi sivulle lämpötilakäyrän jota voisi zoomata ja hiiren päälle vieminen kertoisi ajan ja lämmön?

lämpötila dataa kerätään lämmityskattilan ohjaimesta raspberry pi:n ja RRDtoolin avulla tällä hetkeellä
Graphanalla varmaan saa ihan hetkessä tuon pelittämään.
 
Ulkoinen sovellus pystyy avaamaan toisen sovelluksen ja lähettämään sille samalla komentoriviparametrejä (esim. "firefox.exe -url TechBBS").

Javalla pitäisi toteutaa ohjelma, joka reagoi ulkoisen sovelluksen kutsuihin. Toteuttettava ohjelma on käynnissä, kun kutsuja tulee. Mikä on yksikertaisin tapa toteuttaa toiminnalisuus? Taidot valitettavasti loppuvat siihen vaatimukseen, että ohjelman on oltava käynnissä, kun kutsuja tulee.
 
Nyt tuli pieni ongelma C++:n kanssa. Päänvaivaa tuottaa funktio, jossa vertaillaan vektorissa olevia struct-rakenteita (pointtereiden kautta). Alla huomattavasti yksinkertaistettu tapaus.

Koodi:
struct Tietorakenne {
   int luku;
   string sana;
}

bool funktio(vector<Tietorakenne*>& data1, vector<Tietorakenne*>& data2, int i) {
   if (data1.at(i)->luku > data2.at(i)->luku) {
      return true;
   } else {
      return false;
   }
}

Onko tuota funktiota mitenkään mahdollista kirjoittaa niin, että samalla funktiolla pystyisi kutsukerrasta riippuen vertailemaan joko structin luku- tai sana-jäseniä? Vai onko pakko kirjoittaa kaksi erillistä funktiota, joista toinen vertailee lukua ja toinen sanaa? Ei millään jaksaisi tehdä jokaisesta funktiosta montaa versiota.
 
Nyt tuli pieni ongelma C++:n kanssa. Päänvaivaa tuottaa funktio, jossa vertaillaan vektorissa olevia struct-rakenteita (pointtereiden kautta). Alla huomattavasti yksinkertaistettu tapaus.

Koodi:
struct Tietorakenne {
   int luku;
   string sana;
}

bool funktio(vector<Tietorakenne*>& data1, vector<Tietorakenne*>& data2, int i) {
   if (data1.at(i)->luku > data2.at(i)->luku) {
      return true;
   } else {
      return false;
   }
}

Onko tuota funktiota mitenkään mahdollista kirjoittaa niin, että samalla funktiolla pystyisi kutsukerrasta riippuen vertailemaan joko structin luku- tai sana-jäseniä? Vai onko pakko kirjoittaa kaksi erillistä funktiota, joista toinen vertailee lukua ja toinen sanaa? Ei millään jaksaisi tehdä jokaisesta funktiosta montaa versiota.
lisää funktioon nbeljäs muuttuja joka kertoo mitä vertaillaan. mutta koska noin erilaisa vertailtavat niin joudut kirjoittamaan eri kooodin luvuille ja stringeille kuitekin.
Koodi:
bool funktio(vector<Tietorakenne*>& data1, vector<Tietorakenne*>& data2, int i, int t=0) //toimikos c++:ssa tuo default arvo?
 if (t==0) //tyyppi on intti
  //lukuvertailukoodi
 else // tyyppi on teksti
  //tekstivertailukoodi
 
lisää funktioon nbeljäs muuttuja joka kertoo mitä vertaillaan. mutta koska noin erilaisa vertailtavat niin joudut kirjoittamaan eri kooodin luvuille ja stringeille kuitekin.
Koodi:
bool funktio(vector<Tietorakenne*>& data1, vector<Tietorakenne*>& data2, int i, int t=0) //toimikos c++:ssa tuo default arvo?
 if (t==0) //tyyppi on intti
  //lukuvertailukoodi
 else // tyyppi on teksti
  //tekstivertailukoodi
Tää mullakin kävi mielessä, mutta suorituskykysyistä tää taitaa olla poissuljettu ratkasu. Kyseessä on siis koulutehtävä algoritmikurssiin ja pitäs mahdollisimman nopee algoritmi kirjottaa :D C++:ssa on muuten stringillekkin määritelty tuo <-vertailuoperaattori, eli pitäs toimii samanlaisella koodilla. Pistää isot kirjaimet ennen pieniä, mutta tähän tarkotukseen riittävä.
 
Kyseessä on siis koulutehtävä algoritmikurssiin ja pitäs mahdollisimman nopee algoritmi kirjottaa

Vektori pointtereista on ihan vitun masentava tapaus jos ne on dynaamisesti allokoitu yksi kerrallaan, se indirektio nimittäin syö ihan vitusti performanssia ja on monesti myös turhaa. Algoritmikurssilla yleensä unohdetaan kertoa että oikealla tietokoneella hommat ei toimi niinkuin koulussa opetetaan, ja datan perättäisyys on ihan hemmetin kova juttu kun prosessori osaa prefetchata seuraavat asiat cacheen jo ennen kuin luet niitä.

Eri kutsukerran perusteella eri alkion valinta onnistuu kyllä ilman performanssihintaa, mutta koodista saattaa tulla hieman rumaa riippuen lähestymistavasta. Erityisesti kun sanoit että joka funktiosta pitäisi tehdä kaksi versiota, alkaa hälytyskellot soida että olet ehkä tekemässä nyt jotain pahasti väärin. No, eipä mitään, vastataan nyt kysymykseesi joka tapauksessa, tässä olisi tyypin pohjalta templatoitu accessori, joka sallii myös kirjoittamisen sen läpi.

Koodi:
#include <string>
#include <vector>
#include <iostream>

struct Tietorakenne {
   int luku;
   std::string sana;
 
   template<typename T> const T& value() const;
   template<typename T> T& value();
};

template<> const int& Tietorakenne::value() const { return luku; }
template<> const std::string& Tietorakenne::value() const { return sana; }
template<> int& Tietorakenne::value() { return luku; }
template<> std::string& Tietorakenne::value() { return sana; }

template<typename T>
bool funktio(const std::vector<Tietorakenne*>& data1, const std::vector<Tietorakenne*>& data2, int i) {
    return data1.at(i)->value<T>() > data2.at(i)->value<T>();
}

int main() {
    std::vector<Tietorakenne*> a, b;
    // jumalauta tämä vuotaa kumminkin muistia, mutta ihan sama nyt
    a.push_back(new Tietorakenne{1, "banaani"});
    b.push_back(new Tietorakenne{2, "apina"});
    std::cout << "funktio<int>(a, b, 0) = " << (funktio<int>(a, b, 0) ? "True" : "False") << std::endl;
    std::cout << "funktio<string>(a, b, 0) = " << (funktio<std::string>(a, b, 0) ? "True" : "False") << std::endl;
}

Muuta huomioitavaa:

Käytät vektorien indeksoimiseen .at(i) joka ei ole sama asia a[ i] (perkeleen foorumi ja bbcode nyt vittu), edellinen näistä tekee bounds checkin eli sulla on yhteensä neljä kaksi (sehän olikin tosiaan unsigned, eihän se tarkista kuin ylärajan) ylimääräistä branchia siinä funktiossa sen itse vertailun lisäksi. Tällä on usein huomattava hinta, vaikka prosessori nopeasti oppiikin olettamaan että se bounds check ei ikinä mene yli ja pistää pipelinen sen mukaan. Jos on tarkoitus tehdä nopeaa koodia niin se bounds check tehtäisiin jossain muualla kuin joka alkion kanssa erikseen.

Annoit alunperin pelkkänä referenssinä vektorit, const referenssit on parempi. Const correctness on hyvä opetella aikaisin, sitä kun on todella ankeaa käydä lisäämään mihinkään koodikantaan jälkeenpäin kun siinä tulee kunnon domino-efekti.

Heivaa se using namespace std helvettiin. Tulet kirjoittamaan myöhemmin paljon koodia headereihin jossa olisi tarkoitus määritellä tietorakenteita, ja sitten joudut viljelemään joka luokan sisään sen using namespace std erikseen. Sitähän ei todellakaan headerissa tule sanoa suoraan niin että se std-nimiavaruus vuotaa koko ohjelman globaaliscopeen.

Käytännössä std::vector<Tietorakenne>, elikkäs ilman pointteria, on usein paljon nopeampi kuin pointterin kanssa, kun tietorakenteet ovat pieniä ja yksinkertaisia. Lisäksi jos tuo vektori on ainoa paikka jossa pidetään kirjaa niistä pointtereista, joudut käsin deletoimaan ne alkiot aina samalla kun poistat sieltä vektorista jotain. Tämä tekee monista hienoista jutuista mahdottomia ja rumentaa koodia ihan vitusti. Jos se vektori on niiden tietorakenteiden omistaja ja jostain syystä sen on pakko olla pointteri, voit harkita std::vector<std::unique_ptr<Tietorakenne>> joka hoitaa automaattisen deallokaation puolestasi heti kun vektorista poistetaan pointteri, ja jos kääntäjän optimoinnit on päällä niin unique_ptr:llä ei ole myöskään yksinkertaisessa käytössä mitään performanssihintaa.

Joskus on kätevämpää olla tekemättä tietorakenteista omia structeja ja sanoa vain std:: pair<int, std::string> tai nykyään c++11 kanssa std::tuple<int, std::string> ... varsinkin jos ei tarvitse mitään operaattoreita määritellä sille tietorakenteelle eikä muitakaan jäsenfunktiota.
 
Viimeksi muokattu:
Vektori pointtereista on ihan vitun masentava tapaus jos ne on dynaamisesti allokoitu yksi kerrallaan, se indirektio nimittäin syö ihan vitusti performanssia ja on monesti myös turhaa. Algoritmikurssilla yleensä unohdetaan kertoa että oikealla tietokoneella hommat ei toimi niinkuin koulussa opetetaan, ja datan perättäisyys on ihan hemmetin kova juttu kun prosessori osaa prefetchata seuraavat asiat cacheen jo ennen kuin luet niitä.

Eri kutsukerran perusteella eri alkion valinta onnistuu kyllä ilman performanssihintaa, mutta koodista saattaa tulla hieman rumaa riippuen lähestymistavasta. Erityisesti kun sanoit että joka funktiosta pitäisi tehdä kaksi versiota, alkaa hälytyskellot soida että olet ehkä tekemässä nyt jotain pahasti väärin. No, eipä mitään, vastataan nyt kysymykseesi joka tapauksessa, tässä olisi tyypin pohjalta templatoitu accessori, joka sallii myös kirjoittamisen sen läpi.

Koodi:
#include <string>
#include <vector>
#include <iostream>

struct Tietorakenne {
   int luku;
   std::string sana;
 
   template<typename T> const T& value() const;
   template<typename T> T& value();
};

template<> const int& Tietorakenne::value() const { return luku; }
template<> const std::string& Tietorakenne::value() const { return sana; }
template<> int& Tietorakenne::value() { return luku; }
template<> std::string& Tietorakenne::value() { return sana; }

template<typename T>
bool funktio(const std::vector<Tietorakenne*>& data1, const std::vector<Tietorakenne*>& data2, int i) {
    return data1.at(i)->value<T>() > data2.at(i)->value<T>();
}

int main() {
    std::vector<Tietorakenne*> a, b;
    // jumalauta tämä vuotaa kumminkin muistia, mutta ihan sama nyt
    a.push_back(new Tietorakenne{1, "banaani"});
    b.push_back(new Tietorakenne{2, "apina"});
    std::cout << "funktio<int>(a, b, 0) = " << (funktio<int>(a, b, 0) ? "True" : "False") << std::endl;
    std::cout << "funktio<string>(a, b, 0) = " << (funktio<std::string>(a, b, 0) ? "True" : "False") << std::endl;
}

Muuta huomioitavaa:

Käytät vektorien indeksoimiseen .at(i) joka ei ole sama asia a[ i] (perkeleen foorumi ja bbcode nyt vittu), edellinen näistä tekee bounds checkin eli sulla on yhteensä neljä ylimääräistä branchia siinä funktiossa sen itse vertailun lisäksi. Tällä on usein huomattava hinta, vaikka prosessori nopeasti oppiikin olettamaan että se bounds check ei ikinä mene yli ja pistää pipelinen sen mukaan. Jos on tarkoitus tehdä nopeaa koodia niin se bounds check tehtäisiin jossain muualla kuin joka alkion kanssa erikseen.

Annoit alunperin pelkkänä referenssinä vektorit, const referenssit on parempi. Const correctness on hyvä opetella aikaisin, sitä kun on todella ankeaa käydä lisäämään mihinkään koodikantaan jälkeenpäin kun siinä tulee kunnon domino-efekti.

Heivaa se using namespace std helvettiin. Tulet kirjoittamaan myöhemmin paljon koodia headereihin jossa olisi tarkoitus määritellä tietorakenteita, ja sitten joudut viljelemään joka luokan sisään sen using namespace std erikseen. Sitähän ei todellakaan headerissa tule sanoa suoraan niin että se std-nimiavaruus vuotaa koko ohjelman globaaliscopeen.

Käytännössä std::vector<Tietorakenne>, elikkäs ilman pointteria, on usein paljon nopeampi kuin pointterin kanssa, kun tietorakenteet ovat pieniä ja yksinkertaisia. Lisäksi jos tuo vektori on ainoa paikka jossa pidetään kirjaa niistä pointtereista, joudut käsin deletoimaan ne alkiot aina samalla kun poistat sieltä vektorista jotain. Tämä tekee monista hienoista jutuista mahdottomia ja rumentaa koodia ihan vitusti. Jos se vektori on niiden tietorakenteiden omistaja ja jostain syystä sen on pakko olla pointteri, voit harkita std::vector<std::unique_ptr<Tietorakenne>> joka hoitaa automaattisen deallokaation puolestasi heti kun vektorista poistetaan pointteri, ja jos kääntäjän optimoinnit on päällä niin unique_ptr:llä ei ole myöskään yksinkertaisessa käytössä mitään performanssihintaa.

Joskus on kätevämpää olla tekemättä tietorakenteista omia structeja ja sanoa vain std:: pair<int, std::string> tai nykyään c++11 kanssa std::tuple<int, std::string> ... varsinkin jos ei tarvitse mitään operaattoreita määritellä sille tietorakenteelle eikä muitakaan jäsenfunktiota.

No huh, nyt tuli sellanen vastaus et antaisin ainakin kolme peukkua jos pystyis. Templateja ei oo koskaan meille opetettu, mutta vaikuttaa just siltä mitä tähän kohtaan tarvisin, pitääpi kokeilla jos saisin toimimaan. Voi tää toki olla lähtökohtasesti vääräkin toteutus, mutta tähän hätään ainoo mitä keksin. Tarkoituksena on siis järjestää jonkinnäköstä listaa noista Tietorakenteista ja tähän tarkotukseen mulla on erilaisia sorttausfunktioita, joita käytetään vähän tilanteesta riippuen. Jos samaa funktiota ei voi käyttää structin jokaisen alkion avulla sorttaamiseen niin sittenhän kaikista funktioista on tehtävä monta samanlaista versiota, joissa muuttuu vaan se että mihin alkioon viitataan. Tai näin mä luulisin :D

Osa noista huomauttamistas typeryyksistä johtuu ihan vaan siitä, että tää on vaan harjoitustyö ja osa koodistakin on saatu valmiina. Esimerkiksi tosta vektorista ei oo missään vaiheessa tarkoitus poistaa tavaraa, ellei sitä halua tyhjentää kokonaan. Arvostelussakin vaikuttaa vain tehtyjen algoritmien asymptoottinen nopeus, mutta ihan mielenkiinnosta ja itseäni varten koitan viilata tätä myös muuten nopeammaksi. Vaihdoin jokaisen .at():in []-operaattoriksi ja ohjelman suoritusaika tippui aika tarkasti puoleen. Tälläsiä vihjeitä ku sais koulustakin :tup: Pitää vielä koittaa, että mitä jos noita tietorakenteita ei tallentaiskaan pointtereina.
 
Jos samaa funktiota ei voi käyttää structin jokaisen alkion avulla sorttaamiseen niin sittenhän kaikista funktioista on tehtävä monta samanlaista versiota, joissa muuttuu vaan se että mihin alkioon viitataan. Tai näin mä luulisin :D

Tämän voi tehdä templatoimalla funktion niin että komparaattori annetaan parametrina, jolloin tapauskohtaisesti kirjoitetaan pelkästään se vertailufunktio uusiksi.

Onko sulla C++11 käytössä? Todennäköisesti on. Ohessa esimerkki templatoidusta komparaattorista joka annetaan lambda-funktiona:

Koodi:
#include <string>
#include <vector>
#include <iostream>

struct Tietorakenne {
   int luku;
   std::string sana;
};

std::ostream& operator<<(std::ostream &o, const Tietorakenne &v) {
    return o << "{" << v.luku << ", " << v.sana << "}";
}

template<typename T>
void tee_jotain(const std::vector<Tietorakenne>& data, T vertailija) {
    std::cout << data[0];
    std::cout << " " << (vertailija(data[0], data[1]) ? "on" : "ei ole") << " pienempi kuin ";
    std::cout << data[1] << std::endl;
}

int main() {
    std::vector<Tietorakenne> foo = { {1, "banaani"}, {2, "apina"} };
    std::cout << "tapaus 1: ";
    tee_jotain(foo, [](const Tietorakenne &a, const Tietorakenne &b) -> bool { return a.luku < b.luku; });
    std::cout << "tapaus 2: ";
    tee_jotain(foo, [](const Tietorakenne &a, const Tietorakenne &b) -> bool { return a.sana < b.sana; });
}

Arvostelussakin vaikuttaa vain tehtyjen algoritmien asymptoottinen nopeus

Josta on yllättävän harvoin hyötyä tosielämässä, kun usein ne naiivit algoritmit ja tietorakenteet toimii nopeammin siihen asti kunnes dataa alkaa olla paljon, riippuen toki myös siitä mitä sillä datalla ollaan tekemässä. Tosielämässä myös merkitsee mm. heapin eheys joka on vektorilla parempi, ja ennenkaikkea koodaajan tuhlaama aika joka on sitä parempi mitä yksinkertaisempi systeemi on käytössä. Tyhmät vektorit ja std::sort() järjestämiseen (välittämättä siitä mitä algoritmia se käyttää) on 99% ajasta riittävä, ja sitten kun ei ole niin sen näkee profilerilla että nyt pitäis tehdä jotain.

Koulussa varmaan käsketään käyttämään sitä .at() koska se viskoo heti exceptionia sitten kun mennään rajojen yli ja on melko selkeää, kun taas operator[] kanssa voit korruptoida muistia kun se ei tosiaan tarkista sun puolestasi että tehdäänkö nyt jotain laillista vai ei. Sitten kun tulee access violationia tai SIGSEGViä niin tiedät kusseesi jotain, mutta onhan se perkele nopeampi kun ei kokoajan tarkistella niitä rajoja.
 
Muzzyn tapa taitaa olla parempi noin niinkuin yleisessä käytössä, jos ja kun ei ole järkevää mahdollisuutta lisätä jäsenfunktioita johonkin kolmannen osapuolen koodiin.

Jos taas tilanne on tämä, ja kaikki on mahdollista, niin itse varmaan tekisin näin:

Koodi:
    struct Tietorakenne
    {
        int luku;
        std::string sana;
 
        operator                int(){ return luku; }
        operator const std::string&(){ return sana; }
    };
 
    template< typename T >
    bool vertaa( const T &a , const T &b )
    {
        return a > b;
    }

    int main( void )
    {
       // Niin. Vuotaahan nämäkin, mutta nih....
       std::vector<Tietorakenne*> a = { new Tietorakenne{ 1 , "banaani" } };
       std::vector<Tietorakenne*> b = { new Tietorakenne{ 2 , "apina"   } };

       bool luku = vertaa<     int     >( (*a[0]) , (*b[0]) );
       bool sana = vertaa< std::string >( (*a[0]) , (*b[0]) );

       // Couttia ei tueta :(
       printf( "funktio<int    >(a,b,0) = %s \n" , (luku) ? "True" : "False" );
       printf( "funktio<string >(a,b,0) = %s \n" , (sana) ? "True" : "False" );

    return 0;
    }


Edit1: Ei saatana miten tämä raiskautuu tässä formatoinnissa.... Pidennetään hieman koodia selkeyden nimissä.

Edit2: Noniin. Ja omaakin koodia lipsahti alkuun. Jos joku näki, niin ignooratkaa :D

Edit3: Ja kyllä. Minulla on suljefetissi... Niitä tulee käytettyä tarpeettomasti todella usein, ihan vain esteettisistä syistä.

Edit4: Heitin turhan structin mäkeen... Liikaa pyöri std::sortin komparaattori mielessä.
 
Viimeksi muokattu:
operator int(){ return luku; }

Kääk. Implisiittiset konversio-operaattorit ovat ainakin minun koodikannoissani aiheuttaneet liian usein päänvaivaa kun ennenpitkää rupeaa tulemaan vahinko-konversioita ja sitten on hauska debugata että miksi hemmetissä se koodi tekee niinkuin tekee. Olen kovasti koittanut välttää niitä itse, enkä ole ainoa, sillä esimerkiksi Googlen oma C++ style guide kieltää implisiittiset konversiot poikkeuksetta. Ovathan ne ihan kivoja niinkauan kuin kaikki toimii niinkuin odottaisikin, ei siinä mitään :)
 
Kääk. Implisiittiset konversio-operaattorit ovat ainakin minun koodikannoissani aiheuttaneet liian usein päänvaivaa kun ennenpitkää rupeaa tulemaan vahinko-konversioita ja sitten on hauska debugata että miksi hemmetissä se koodi tekee niinkuin tekee. Olen kovasti koittanut välttää niitä itse, enkä ole ainoa, sillä esimerkiksi Googlen oma C++ style guide kieltää implisiittiset konversiot poikkeuksetta. Ovathan ne ihan kivoja niinkauan kuin kaikki toimii niinkuin odottaisikin, ei siinä mitään :)

Joo. Vahinkoja noiden kanssa kyllä pääsee todellakin sattumaan, eikä se välttämättä ole kenenkään kannalta kivaa, kun jossain päin ohjelmaa Apina -olioista kuoriutuu Banaaneja ilman mitään varsinaista näkyvää ja hyvää syytä. :p

Ei tuota tosiaan universaaliksi ratkaisuksi voisi suositella, mutta hyvin paikallinen, yhden käännösyksikön sisällä tapahtuva tempaus varmaan menettelee. Ehkä toimi alkuperäiselle kysyjälle myös todella minimalistisena esimerkkinä templatejen luovan käytön mahdollisuuksista.

Eikä tuon konversio "tempun":kaan tunteminen haitaksi ole, kuten ei gotonkaan. Kunhan ei rupea perseilemään niiden kanssa.

Kieli keskellä suuta kyllä näiden kanssa täytyy olla, muuten tulee sotku, itku ja parku. :S
 
Kiitti paljon vastauksista! Näiden innoittamana tein elämäni ekat templatet, joiden avulla annoin funktioille parametrina member pointerin siihen structin jäseneen, jota haluttiin vertailla.
 
Ihmetystä aiheuttaa c# Windows.Gaming.Input luokka. Tarkoitus olisi tehdä ohjelma johon saa syötettyä bonen padista infoa, mutta ohjelma jumittaa aina kun jään lukemaan ohjaimen tietoa.

Koodi:
double right, left;
GamepadReading pad = Gamepad.Gamepads.FirstOrDefault().GetCurrentReading();

while (tapahtuu ihmeitä) {
                right = pad.RightTrigger;
                left = pad.LeftTrigger;
}

kutakuin pähkinänkuoressa jotain tällaista yritän.. Vasemman sekä oikean liipaisimen arvo pitäisi saada talteen. UWP ohjelma ja ikkuna jumahtaa aina kun looppi alkaa. Onko jollain kokemusta moisesta ja vinkkiä oikeaan suuntaan? :)
 
Laitappa while looppiin loppuun sleep tms. tai sellainen lauseke joka antaa ohjelmalle aikaa käsitellä Windows:in viestejä (message loop). Toinen tapa on että luot säikeen (thread) jossa sitten pollaat padin arvoja.
 
Kiitoksia! Tämä nyt ei ole mikään työnalla oleva asia vaan lähinnä mietin, että onko tähän joku yleisesti hyväksytty tapa taikka sääntö jota käytetään.

On, tietokanta. Tommoseen key, value -tarkoitukseen toimii vaikka Redis, tai jos on moninutkaisempaa dataa, niin MongoDB ja joku relaatiokanta kuten MySQL/MariaDB tai PostgreSQL.

Tai jos ehdottomasti itse haluat serialisoida, niin laita ne listat HashMappiin ja serialisoi se. Tai jos et halua aina lukea koko mänttiä muistiin niin sitten omiin filuihinsa a.dat, b.data ja c.dat ne.

Onhan tossa vaihtoehtoja.
 
Laitappa while looppiin loppuun sleep tms. tai sellainen lauseke joka antaa ohjelmalle aikaa käsitellä Windows:in viestejä (message loop). Toinen tapa on että luot säikeen (thread) jossa sitten pollaat padin arvoja.

Kiitoksia, async ratkaisi asian! :) Helppoa se on kun osaa...
 
Yritän muokata tätä userskriptia ohjaamaan kaikki .mobi-linkit työpöytäsivulle:
Koodi:
// ==UserScript==
// @match      http://*.m.wikipedia.org/*
// @match      https://*.m.wikipedia.org/*
// @run-at    document-start
// ==/UserScript==

var m_url = window.location.href;
var url = m_url.replace(".m.", ".");

window.location = url;

Miten? Oma viritelmäni saa kaikki sivut päivittymään loputtomasti ja Greasemonkey tulkitsee sen virheelliseksi:
Koodi:
// @match      http://*.m.*/
// @match      https://*.m.*/

En edes tiedä onko kyseinen skripti virheetön, se oli ensimmäinen minkä löysin tähän tarkoitukseen ja hyvin yksinkertainen.
Muokkaan vain kahta kyseistä riviä.
 
Viimeksi muokattu:
Yritän muokata tätä userskriptia ohjaamaan kaikki mobi-linkit työpöytäsivulle:
Koodi:
// ==UserScript==
// @match      http://*.m.wikipedia.org/*
// @match      https://*.m.wikipedia.org/*
// @run-at    document-start
// ==/UserScript==

var m_url = window.location.href;
var url = m_url.replace(".m.", ".");

window.location = url;

Miten? Oma viritelmäni sai kaikki sivut päivittymään loputtomasti tai Greasemonkey tulkitsee sen virheelliseksi:

Koodi:
// @match      http://*.m.*/
// @match      https://*.m.*/

En edes tiedä onko kyseinen skripti virheetön, se oli ensimmäinen minkä löysin tähän tarkoitukseen ja hyvin yksinkertainen.
Toimisko
window.location.replace (url);
 
Toimisko
window.location.replace (url);

Ei vielä, omassa säännnössä mättää:

OHRXtBD.png
 
Niin kuin tuo virheilmoituskin kertoo, vika on match patternissa. Hostissa voi olla kaiketi vain yksi tähti. Match Patterns - Google Chrome

Include-säännössä voi käyttää RegExpiä. Tämä vaikuttaisi toimivan. Lisäsin tuohon jos host alkaa m:llä.
Koodi:
// ==UserScript==
// @name mobile2desktop
// @include /.*://(?:m\.|[^/]*\.m\.).*/
// @run-at document-start
// ==/UserScript==

var m_url = window.location.href;
var url = m_url.replace(/:\/\/(?:m\.|([^\/]*\.)m\.)/, "://$1");
window.location = url;
 
mitä mieltä olette kestääkö RaspberryPi:n muistukortti jos siellä pyörittää InfluxDB? vai onko joku "varmempi" ratkaisu parempi
tietokantaan kerättäisiin lämpötila dataa ja muuta oleellista tietoa kotiautomaatiosta ja ajettaan ulos Grafana kautta.

kiitokset @©©© Graphana vihjeestä, lähti tuo vanhentunut RRDTool vaihtoon
 
Mikäs olis joku järkevä keino lukea tiedosto.log serveriltä ja printata sitä "reaaliajassa" html diviin?
 
Mikäs olis joku järkevä keino lukea tiedosto.log serveriltä ja printata sitä "reaaliajassa" html diviin?

Siinä voisi ehkä käyttää WebSocket -rajapintaa. Serverillä lokin seuranta, ja puskeminen sockettiin, joka sitten joka viestin mukaan ylläpitää sivua.
 
Kiitoksia JoniS ja TheMell, tuo serveri-idea ilmeisesti toimii tuossa mun tapauksessa just niin kuin haluankin, potkaisitte mua oikeaan suuntaan. Ensimmäinen hyvin riisuttu testiprotokoodi on kasassa ja saan siitä kivasti ulos sille lähetetyn stringin ja vasteaika on ihan eri luokkaa kuin vanhaan tapaan että python käynnistetään joka kerta uusiksi. Nyt viiveenä tulee olemaan käytännössä enää nettiyhteyden nopeus ja OLA-serverin oma hitaus lähettää DMX-data eth-dmx -palikalle, itse python-skripti ei käytännössä enää aiheuta viivettä hommaan.

Samaan serverityyliin pitää kirjoittaa nettiradiosoittimen ohjauksen koodikin uusiksi, siinä pahimpana ongelmana on ollut pitkä viive kun joka kerta kun käyttöliittymästä painaa nappia niin skripti kirjautuu soittimeen ja vasta sitten saa lähetettyä komentoja ja tuo kirjautuminen ottaa aikaa reilun sekunnin. Tuolla serverityylillä voi pitää session koko ajan auki ja komennot menevät läpi silmänräpäyksessä.

Nyt vaan kaljaa koneeseen ja koodia vääntämään...
Kiitoksia vielä kerran! Tuo idea toimii loistavasti! Nyt olen vääntänyt lähes koko vanhan ohjaushässäkän uusiksi pohjautuen tuohon python-serveriin ja kaikki on helpompaa ja nopeampaa. Kirjautumista/autentikointia vaativat laitteet ovat nyt kokoajan kirjautuneena ja keepalivella pidän ne siinä tilassa joten niille menee komennot silmänräpäyksessä. Ja ennen piti olla kymmeniä eri skriptejä huolehtimassa eri asioita ja ne on nyt saatu keskitettyä yhteen paikkaan eli enää ei tarvitse muokata kymmeniä fileitä että saa päivitettyä jotain toiminnallisuutta.

Vielä on vähän koodattavaa ja testattavaa että voin ottaa uuden systeemin "tuotantoon" mutta näillä näkymin uuden systeemin yliheiton saa hoidettua ensi viikon aikana. Tuo yksi pieni asia poiki aikamoisen parannuksen järjestelmään. Olihan tuossa paljon koodattavaa mutta hyödyt kyllä kuittaavat vaivan. Ylläpito ainakin helpottui pirusti ja nyt sai esim telkkarikanavat helposti ja järkevästi sqlite-kantaan ja sieltä saa kätevästi haettua samat tiedot useampaan paikkaan. Telkkarikanavat/muut kaukosäädinkomennot olivat muutenkin totaalinen purkkaviritelmä kun IR-komentojen lähettäminen shelliskripteillä oli hieman haastavaa kun on monta käskytettävää laitetta.
 
Alkeellinen kysymys C:hen (tai C++, java)
Tarvitsisin tyypin jonka saa arvojoukko on rajattu esim 0, 1, 2, 3, 4 eli jolloin:
Koodi:
while (1) {
mode++;
printf(mode)
}

0
1
2
3
4
0
1
...jne
 
...nollaa muuttuja, kun menee rajan yli? Ei kait siihen sen kummempaa tarvitse.

Javassahan voit toteuttaa esim. luokan, joka pitää sisällään kokonaisluvun ja tiedon minimi- ja maksimirajasta, ja sitten kasvatusmetodin joka toimii kuin ++, paitsi muuttaa kokonaisluvun alarajan kun ylärajan yli on menty. Riippuen ihan käyttötarkoituksesta.
 
Tai kasvatat sitä mode-muttujaa kuten yllä ja käytät moduloa: printf(mode % 5);

Riippuu varmaan käyttötarpeesta, millainen ratkaisu on passelein.
 
Joo muuttujan nollaus onnistuu kyllä.

Lähinnä ajattelin että jos integer tyyppi on määritelty 16 bittiseksi niin voinko määritellä oman 2 bittisen tyypin, tai määrittää custom overflow rajat. Tokihan se veisi silti yhden tai kaksi tavua muistia (?)
 
Lähinnä ajattelin että jos integer tyyppi on määritelty 16 bittiseksi niin voinko määritellä oman 2 bittisen tyypin, tai määrittää custom overflow rajat. Tokihan se veisi silti yhden tai kaksi tavua muistia (?)
Ainakaan minulla ei ole tiedossani ohjelmointikieltä, jossa tyyppijärjestelmä taipuisi nätisti ihan tuollaiseen (vaikkakin se olisi usein ihan toivottavaa). Voi sellaisia ollakin, mutta ainakaan yleisimmissä kielissä moista ei taida olla.
 
Käsittääkseni Ada taipuu. Noilla halutuilla kielillä ei onnistu. Ada on hieno kieli ja sillä on koodattu Apollot aikoinaan ja mannerten väliset ohjukset...
 
Miten teen Kubuntussa staattisen (eli kiinteän) ip-osoitteen langalliselle verkolle?
Paljon olen googlaillut, enkä saanut sitä vaihdettua millään.

Myöskään welcome messagea en saa tuohon ssh yhteyteen tehtyä...

Veikkaan, että olet väärässä ketjussa ja väärällä alueella. Kokeiles Linux-ketjua tuolla ohjelmistopuolella.
 
Miten teen Kubuntussa staattisen (eli kiinteän) ip-osoitteen langalliselle verkolle?
Paljon olen googlaillut, enkä saanut sitä vaihdettua millään.

Myöskään welcome messagea en saa tuohon ssh yhteyteen tehtyä...

minun lukutaito petti.. :(
Asetukset löytyy täältä.
Koodi:
sudo nano /etc/network/interfaces

Muuta se yhteys staattiseksi jonka haluta. (Luultavasti eth0)
Koodi:
iface eth0 inet static
    address 192.168.xxx.xxx
    netmask 255.255.255.0
    gateway 192.168.xxx.xxx

ssh sisäänkirjautumis viesti saa päälle täältä.
Koodi:
sudo nano /etc/ssh/sshd_config

Poista kommentointi (#) riviltä.
Koodi:
#Banner /etc/issue.net

Kirjoita viesti tiedostoon
Koodi:
sudo nano /etc/issue.net

Käynnistä ssh uudelleen
Koodi:
sudo service ssh reload
 
Nettisivuohjelmoitiin liittyvää:

Onko nykyään jotain uudenaikaista meta hakusanojen esittämiseen, että näkyy hakukoneilla?

Tarkoitan nyt sitä, kun perinteinen tapa on laittaa näitä sinne sivuille-->
<meta name="description" content="Suomen myynti halvalla">
<meta name="keywords" content="suomi, kekkonen, kekkonen, kekkonen">

Kattelin, että on jonkinlaista SEO hässäkkää ja äkkiseltään en tajunnut. Vaatiiko jotain erikoisohjelmia? Onko tämä enemmänkin wordpressiin liittyvää sinne, kun tuskin voi tuosta noin vaan lisätä noita yllä olevia pätkiä?

Sitten oli esim. Googlen esim.<meta name=”google-site-verification” content=”rc2RXSkjV5rz9P2s2hTwdDsnwTu4tD-gmruKUrqBGjs” />
Eli onko tuollainen todennus tarpeellinen, että näkyy paremmin Googlen hakukoneella vai onko turha kilke?
 
Keywordit tuskin auttavat millään relevantilla hakukoneella. Muutoin metadataa kannattaa käytää jo ihan käyttäjien takia. Tuo google-site-verification liittyy Search Consolen käyttöön, tuskin nostaa näkyvyyttä. Description taas saatetaan näyttää hakutuloksissa, mutta tuskin vaikuttaa näkyvyyteen.

En tunne aihetta kovin hyvin, mutta omilla keinoilla voi parantaa sivun näkyvyyttä esim. käyttämällä HTTPS:ää, käyttämällä oikeanlaista semanttista html:lää (esim. kuviin alt-attribuutit), tekemällä mobiiliystävälliset sivut, linkittämällä omille sivuille muualta jne. Joku varmaan osaa kertoa enemmän relevantteja keinoja.
 
Siis hakukoneet ei itsekseen hae sivustoista tietoja metadatan perusteella? Sivut pitää itse ilmoittaa hakukoneille?

Joskus muinoin käytin vanhaan sivustoon jonkinlaista automaattikilkettä, joka ilmoitti suunnilleen sataan hakukoneeseen sivut ja voi että kun sähköposti tulvi "roskapostia" tuon tempun jälkeen.
 
Kyllä hakevat myös automaattisesti.

Löysinkin googlelta sivun missä pystyi lisäämään urlin ja avainsanat. "Google lisää uusia sivustoja hakemistoon ja päivittää olemassa olevia sivustoja aina indeksoidessaan verkkoa. Jos sinulla on uusi URL-osoite, kerro siitä meille täällä. Emme lisää kaikkia lähetettyjä URL-osoitteita hakemistoomme, emmekä voi arvioida tai taata lisäysajankohtaa tai sitä, lisätäänkö URL-osoitettasi lainkaan hakemistoomme."

Jostain syystä ilmoittaa vaan "Pyyntösi on vastaanotettu, ja se käsitellään hetken kuluttua." ja mitään ei tapahdu. Ihme hetki..
Kuitenkin näkyykin jo google haulla.
 

Statistiikka

Viestiketjuista
261 776
Viestejä
4 546 818
Jäsenet
74 846
Uusin jäsen
Urnaakkeliz

Hinta.fi

Back
Ylös Bottom