Pieniä kysymyksiä ohjelmoinnista

Liittynyt
27.03.2017
Viestejä
1 610
Olen C# aloittelija. Miksi en löydä projektista (vai solutionista?) tiettyä muuttujaa Visual Studio 2019 Community:llä?

Tarkoitukseni oli muuttaa muuttujan VeryLow.DistanceFromTakeOffLocation arvo käsin:
1. Kloonasin suoraan VS2019:llä
2. Avasin VS2019:llä Source/BriefingRoom.sln (kokeilin myös Source/BriefingRoom.csproj)
3. Ctrl+f ja hakukenttään VeryLow.DistanceFromTakeOffLocation
4. Ei löydy!?

Hämmentyneenä etsin sen sitten käsin ja se löytyi Database/Objectives.ini:stä. Miksi VS2019 ei etsinyt myös tuolta Database-hakemistosta? Sitä ei tosin näy VS:n puolella Solution Explorerissa, eli nuin kai sen pitäisikin toimia, mutta hämää paljon kun se silti tuli gitistä samaan syssyyn ja lukeehan se ohjelmakin tuota tiedostoa!?
 
Liittynyt
17.01.2018
Viestejä
1 221
Lisäsin tuohon vielä jokaiselle riville pelaajan nykyisen tiimin nimen. Hakuaikaa tuli yli tuplat lisää. Meniköhän joku väärin? Ilman tiimiä hakuaika on 0,5s ja tiimin kanssa 1,3s.

Tässä ratkaisuni:
SQL:
          SELECT
          "Player"."id",
          "Team"."name",
          SUM("Stats"."goals") AS "goals",
          SUM("Stats"."assists") AS "assists"
          FROM
          "Player" INNER JOIN
          (
                  SELECT
                      "GameStats"."playerId" AS "playerId",
                      "GameStats"."goals" AS "goals",
                      "GameStats"."assists" AS "assists",
                      ROW_NUMBER() OVER (PARTITION BY "GameStats"."playerId" ORDER BY "Game"."gameDate" DESC) AS "seqnum"
                  FROM
                  "Game" JOIN "GameStats" ON (
                      "Game"."id" = "GameStats"."gameId"
                  )
          ) "Stats" ON (
              "Player"."id" = "Stats"."playerId"
          )
            JOIN "PlayerTeam" ON "Player"."id" = "PlayerTeam"."playerId"
            JOIN "Team" ON "PlayerTeam"."teamId" = "Team"."id"
            WHERE
            "Stats"."seqnum" < 6 AND
            "PlayerTeam"."endDate" IS NOT NULL
            GROUP BY
            "Player"."id",
            "Team"."name"
Mulla on siis PlayerTeam-niminen taulukko, jossa on viittauksen kaikkiin pelaajien aikaisempiin tiimeihin ja nykyinen tiimi on se rivi, jossa endDate on NULL. Tässä on sellainen ongelma, että nyt käsittääkseni jokaisen pelaajan tilastot jakautuu joukkueiden mukaan, mutta tämä ei ole haluttua. Haluaisin tehdä niin, GROUP BY:ssä lasketaan kaikki tilastot tiettyjen pelien osalta yhteen ja vasta sen jälkeen lisätään hakutulokseen muu "metadata", kuten esimerkiksi juuri tuo tiimi ja kaikki muu Player-taulukosta löytyvä data.
Tulee hidas siksi että tiimit lisätään ennen summausta. Lisäksi jos nykyisellä tiimillä enddate on null niin tuolla yllä olevalla saat kaikki muut paitsi nykyisen.

Eli jos ymmärsin oikein niin enddate is null olisi oikea ehto, silloin joinin ei pitäisi lisätä rivimäärää olettaen että voi kuulua kerrallaan vain yhteen tiimiin.
Saattaa toimia silti paremmin niin että pidät alkuperäisen kyselyn ennallaan (summat pelaajittain) ja liität sen kylkeen muut tiedot jolloin ruvejä on enää 1 per pelaaja.

Jos rivejä on paljon niin join ja ehtosarakkeille kannattaa tehdä indeksit.
Samoin jos sisäkkäisiä kyselyjä tulee paljon niin näkymät auttavat, ei tehossa mutta selkeyttää.
 
Liittynyt
19.10.2016
Viestejä
1 367
Olen C# aloittelija. Miksi en löydä projektista (vai solutionista?) tiettyä muuttujaa Visual Studio 2019 Community:llä?

Tarkoitukseni oli muuttaa muuttujan VeryLow.DistanceFromTakeOffLocation arvo käsin:
1. Kloonasin suoraan VS2019:llä
2. Avasin VS2019:llä Source/BriefingRoom.sln (kokeilin myös Source/BriefingRoom.csproj)
3. Ctrl+f ja hakukenttään VeryLow.DistanceFromTakeOffLocation
4. Ei löydy!?

Hämmentyneenä etsin sen sitten käsin ja se löytyi Database/Objectives.ini:stä. Miksi VS2019 ei etsinyt myös tuolta Database-hakemistosta? Sitä ei tosin näy VS:n puolella Solution Explorerissa, eli nuin kai sen pitäisikin toimia, mutta hämää paljon kun se silti tuli gitistä samaan syssyyn ja lukeehan se ohjelmakin tuota tiedostoa!?
En nyt jaksa tarkistaa, kun on muutenkin omasta mielestäni hyvä arvaus, mutta siis näin: Ctrl + F hakee useimmissa ohjelmissa vain auki olevasta tiedostosta, kun taas Ctrl + Shift + F hakee kaikista projektin tms. tiedostoista. Sinulla kuulostaa siis olevan liian suppea haku käytössä.
 
Liittynyt
17.10.2016
Viestejä
242
Olen C# aloittelija. Miksi en löydä projektista (vai solutionista?) tiettyä muuttujaa Visual Studio 2019 Community:llä?
enä etsin sen sitten käsin ja se löytyi Database/Objectives.ini:stä. Miksi VS2019 ei etsinyt myös tuolta Database-hakemistosta? Sitä ei tosin näy VS:n puolella Solution Explorerissa, eli nuin kai sen pitäisikin toimia, mutta hämää paljon kun se silti tuli gitistä samaan syssyyn ja lukeehan se ohjelmakin tuota tiedostoa!?
Siinä hakulaatikossa on useampi optio millä rajata scopea kohdistuuko se avattuun dokkariin, projektiin vai koko solutioniin. Lisäksi on vielä se match case -täppä, jolla rajataan merKkiKokoa hakutermistä.
 
Liittynyt
23.10.2016
Viestejä
554
Tulee hidas siksi että tiimit lisätään ennen summausta. Lisäksi jos nykyisellä tiimillä enddate on null niin tuolla yllä olevalla saat kaikki muut paitsi nykyisen.

Eli jos ymmärsin oikein niin enddate is null olisi oikea ehto, silloin joinin ei pitäisi lisätä rivimäärää olettaen että voi kuulua kerrallaan vain yhteen tiimiin.
Saattaa toimia silti paremmin niin että pidät alkuperäisen kyselyn ennallaan (summat pelaajittain) ja liität sen kylkeen muut tiedot jolloin ruvejä on enää 1 per pelaaja.

Jos rivejä on paljon niin join ja ehtosarakkeille kannattaa tehdä indeksit.
Samoin jos sisäkkäisiä kyselyjä tulee paljon niin näkymät auttavat, ei tehossa mutta selkeyttää.
Miltäs tämä näyttää:

SQL:
SELECT
    "Player"."id",
    "Player"."lastName",
    "Team"."name",
    "PlayerStats"."goals",
    "PlayerStats"."assists"
FROM
    (
        SELECT
            "Player"."id",
            SUM("Stats"."goals") AS "goals",
            SUM("Stats"."assists") AS "assists"
        FROM
            "Player"
            INNER JOIN (
                SELECT
                    "GameStats"."playerId" AS "playerId",
                    "GameStats"."goals" AS "goals",
                    "GameStats"."assists" AS "assists",
                    ROW_NUMBER() OVER (
                        PARTITION BY "GameStats"."playerId"
                        ORDER BY
                            "Game"."gameDate" DESC
                    ) AS "seqnum"
                FROM
                    "Game"
                    JOIN "GameStats" ON (
                        "Game"."id" = "GameStats"."gameId"
                    )
            ) "Stats" ON (
                "Player"."id" = "Stats"."playerId"
            )
        WHERE
            "Stats"."seqnum" < 6
        GROUP BY
            "Player"."id"
    ) AS "PlayerStats"
    JOIN "Player" ON "PlayerStats"."id" = "Player"."id"
    JOIN "PlayerTeam" ON "Player"."id" = "PlayerTeam"."playerId"
    JOIN "Team" ON "PlayerTeam"."teamId" = "Team"."id"
WHERE
    "PlayerTeam"."endDate" IS NULL
Nyt tämä toimii hyvin pitkälti niin kuin haluankin. Pystyn Player-taulukon relaatioita joinailemaan tilastojen laskennan jälkeen miten haluan.

Mietityttää tuo WHERE ehto. Joinaan PlayerTeam taulukkoon kaikki joukkueet. Tapahtuuko tuossa nyt niin, että joinaan myös se joukkueet, joissa endDate ei ole null ja filtteröinti tapahtuu vasta lopputuloksesta, vai tajuaako tietokanta automaattisesti olla joinaamatta niitä rivejä, jotka WHERE-lauseke sulkee pois?
 
Liittynyt
17.01.2018
Viestejä
1 221
Miltäs tämä näyttää:

SQL:
SELECT
    "Player"."id",
    "Player"."lastName",
    "Team"."name",
    "PlayerStats"."goals",
    "PlayerStats"."assists"
FROM
    (
        SELECT
            "Player"."id",
            SUM("Stats"."goals") AS "goals",
            SUM("Stats"."assists") AS "assists"
        FROM
            "Player"
            INNER JOIN (
                SELECT
                    "GameStats"."playerId" AS "playerId",
                    "GameStats"."goals" AS "goals",
                    "GameStats"."assists" AS "assists",
                    ROW_NUMBER() OVER (
                        PARTITION BY "GameStats"."playerId"
                        ORDER BY
                            "Game"."gameDate" DESC
                    ) AS "seqnum"
                FROM
                    "Game"
                    JOIN "GameStats" ON (
                        "Game"."id" = "GameStats"."gameId"
                    )
            ) "Stats" ON (
                "Player"."id" = "Stats"."playerId"
            )
        WHERE
            "Stats"."seqnum" < 6
        GROUP BY
            "Player"."id"
    ) AS "PlayerStats"
    JOIN "Player" ON "PlayerStats"."id" = "Player"."id"
    JOIN "PlayerTeam" ON "Player"."id" = "PlayerTeam"."playerId"
    JOIN "Team" ON "PlayerTeam"."teamId" = "Team"."id"
WHERE
    "PlayerTeam"."endDate" IS NULL
Nyt tämä toimii hyvin pitkälti niin kuin haluankin. Pystyn Player-taulukon relaatioita joinailemaan tilastojen laskennan jälkeen miten haluan.

Mietityttää tuo WHERE ehto. Joinaan PlayerTeam taulukkoon kaikki joukkueet. Tapahtuuko tuossa nyt niin, että joinaan myös se joukkueet, joissa endDate ei ole null ja filtteröinti tapahtuu vasta lopputuloksesta, vai tajuaako tietokanta automaattisesti olla joinaamatta ne rivit, jotka WHERE-lauseke lukee pois?
Riippuu siitä minkälaisen suoritussuunnitelman kanta tekee tuosta kyselystä.
Jos tekee "oikein" niin enddate rajaus tehdää ensin ja sitten join. Saattaa vaatia indeksin enddate kentälle.
Katso kyselyn plan kannasta niin näet miten se oikeasti suoritetaan.
 
Liittynyt
23.10.2016
Viestejä
554
Riippuu siitä minkälaisen suoritussuunnitelman kanta tekee tuosta kyselystä.
Jos tekee "oikein" niin enddate rajaus tehdää ensin ja sitten join. Saattaa vaatia indeksin enddate kentälle.
Katso kyselyn plan kannasta niin näet miten se oikeasti suoritetaan.
Jotta saan tehtyä endDate rajauksen ensin, niin tarvisi siis wrapata toi vielä yhteen SELECTiin ja tehdä toi viimeinen joini vasta sillä tasolla?
 
Liittynyt
23.10.2016
Viestejä
554
Jos tulkitsen oikein niin pgAdminissa näyttäis siltä, että endDate-filtteröinti tapahtuu ennen kaikkien joukkueiden joinia. :thumbsup:
 
Liittynyt
17.01.2018
Viestejä
1 221
Jotta saan tehtyä endDate rajauksen ensin, niin tarvisi siis wrapata toi vielä yhteen SELECTiin ja tehdä toi viimeinen joini vasta sillä tasolla?
Yleensä alikyselyt eivät paranna suorituskykyä vaan päinvastoin.
Pyrin käyttämään niitä vain silloin kun on pakko oikean logiikan vuoksi
 
Liittynyt
23.10.2016
Viestejä
554
SQL:n GROUP BY:lla on mahdollista esim summata useamman rivin arvot toisiinsa. MongoDB:n aggregaatio-frameworkilla onnistuu myös seuraavanlainen operaatio:

Koodi:
goalsAgainst: {
  $sum: {
    $subtract: [
      '$GameStats.shotsAgainst',
      '$GameStats.saves',
    ],
  },
},
Tuo on minulla on siis yksi $group-operaattorin kentistä ja se siinä lasketaan jokaisessa pelissä vastustajan tekemät maalit vähentämällä vastustajan laukaksista omat torjunnat. Onnistuuko samanlainen operaatio jotenkin SQL:ssä GROUP BY -operaattorilla tai jos ei, niin mikä on oikea lähestymistapa? Onko tuon goalsAgainst-kentän pakko olla tallennettuna tietokantaan?
 
Liittynyt
17.10.2016
Viestejä
4 073
SQL:n GROUP BY:lla on mahdollista esim summata useamman rivin arvot toisiinsa. MongoDB:n aggregaatio-frameworkilla onnistuu myös seuraavanlainen operaatio:

Koodi:
goalsAgainst: {
  $sum: {
    $subtract: [
      '$GameStats.shotsAgainst',
      '$GameStats.saves',
    ],
  },
},
Tuo on minulla on siis yksi $group-operaattorin kentistä ja se siinä lasketaan jokaisessa pelissä vastustajan tekemät maalit vähentämällä vastustajan laukaksista omat torjunnat. Onnistuuko samanlainen operaatio jotenkin SQL:ssä GROUP BY -operaattorilla tai jos ei, niin mikä on oikea lähestymistapa? Onko tuon goalsAgainst-kentän pakko olla tallennettuna tietokantaan?
Jos nyt ymmärsin oikein mitä haet takaa, niin:
SQL:
SELECT
  SUM(shotsAgainst) - SUM(saves) AS goalsAgainst
FROM taulu
GROUP BY kolumni_millä_haluat_groupata
 
Liittynyt
17.01.2018
Viestejä
1 221
SQL:n GROUP BY:lla on mahdollista esim summata useamman rivin arvot toisiinsa. MongoDB:n aggregaatio-frameworkilla onnistuu myös seuraavanlainen operaatio:

Koodi:
goalsAgainst: {
  $sum: {
    $subtract: [
      '$GameStats.shotsAgainst',
      '$GameStats.saves',
    ],
  },
},
Tuo on minulla on siis yksi $group-operaattorin kentistä ja se siinä lasketaan jokaisessa pelissä vastustajan tekemät maalit vähentämällä vastustajan laukaksista omat torjunnat. Onnistuuko samanlainen operaatio jotenkin SQL:ssä GROUP BY -operaattorilla tai jos ei, niin mikä on oikea lähestymistapa? Onko tuon goalsAgainst-kentän pakko olla tallennettuna tietokantaan?
Sum(shotsAgainst - saves) as goalsAgainst

Pitäisi olla toiminnallisesti sama. Yleensä samaan pääsee myös erillisillä summilla kuten @edup jo ehti vastata.
 
Liittynyt
23.10.2016
Viestejä
554
Jees kiitoksia. SQL-syntaksi on kyllä paljon mukavampi verrattuna tuohon MongoDB:hen.
 

Lare

Error 404
Liittynyt
13.11.2016
Viestejä
2 165
Onkohan täällä normalisoinnin taitajia? Boyce/Codd-muoto tuottaa hankaluuksia itselle.

Relaatio on S (A, B, C, D), jossa pätee seuraavat. Tuo pitäisi saada Boyce/Codd -muotoon.

{A} -> {B, C, D}
{B} -> {A, D}

Toisen normaalimuodon ehtojahan tuo ei täytä. Jos normalisoin tuon toiseen normaalimuotoon, niin eikö se sen jälkeen täytä myös kolmannen ja Boyce/Codd -normaalimuodon määritykset? Vai onko oma vastaus aivan päin persettä, kuten epäilen?

Eli tulee seuraavat relaatiot:
S1 (A, B, C, D)
S2 (B, A)
Joista pätee:
{A} -> (B, C, D)
{B}-> (A)
 
Liittynyt
21.02.2021
Viestejä
2
miten tehdä tuotesuodattimia. Kaikissa verkkokaupoissa on tuotesuodatin, josta voit valita, että housut ovat sinisiä eikä niissä ole reikiä vaikka. Mietin, miten se tehdään. Käytän verkkosivustollani javascriptiä ja haluan tällaisen suodattimen. mutta miten teen sen?
 
Liittynyt
17.10.2016
Viestejä
7 037
miten tehdä tuotesuodattimia. Kaikissa verkkokaupoissa on tuotesuodatin, josta voit valita, että housut ovat sinisiä eikä niissä ole reikiä vaikka. Mietin, miten se tehdään. Käytän verkkosivustollani javascriptiä ja haluan tällaisen suodattimen. mutta miten teen sen?
Näillä tiedoilla sua on aika lailla mahdoton auttaa. Millaista apua kaipaat siis? Onko tuotteet tietokannassa, etkä osaa suodattaa hakua? Mikä kanta, miten ne tuotteet siellä ovat? Vai pitääkö suodatus tehdä jossain muualla, missä (bäkkärissä, clientissä)? Vai etkö osaa tehdä UI-elementtejä, joilla käyttäjä valitsee filtterit? Vai et osaa ottaa filttereitä huomioon kun haet tuotteita API:sta? Vai oliko kyse jostain muusta? Eli kerros vähän enemmän.
 

Make

Tekee järkeä.
Tukijäsen
Liittynyt
16.10.2016
Viestejä
828
Mulla on Azuressa App Service joka on suojattu AD:lla, sekä Http-trigger Functions App joka kutsuu tuota App Serviceä suoralla URL:lla. Nyt kutsu ei onnistu tietenkään kun AD ei päästä anonyymiä kutsua läpi (tulee herja: "You do not have permission to view this directory or page.")

Miten tuon saisi helpoiten päästämään Functions Appin kutsut läpi? Voiko jotenkin sallia kutsut tietystä URL:sta tms. ? Olen netistä löytänyt vähän saman suuntaisia ongelmia esim. Logic Appista Functions Appiin AD:n läpi, mutta en ole niiden avulla osannut laittaa toimimaan.


Saako Function appista lähtevään kutsuun sisällytettyä noi Tenant, Audience, ClientId ym. mitä tuossa on Logic appiin sisällytetty?
 

Noz

Liittynyt
17.10.2016
Viestejä
118
Pari Nodeen liittyvää pikakysymystä:
1. Ajetaan sovellus tällaisenaan. Tulokseksi saadaan alla oleva virhe. Jos taas inquirer.js:n kommentoitu koodi otetaan käyttöön (ja tietenkin poistetaan 'const mainOptions...' ja ensimmäinen 'module.exports...'), sovellus toimii normaalisti. En vaan keksi, miksei tuo ensimmäinen ratkaisu toimi.
Koodi:
(node:19204) UnhandledPromiseRejectionWarning: TypeError: Cannot destructure property `option` of 'undefined'
or 'null'.
    at run (M:\nextCloud\dev\testi\src\index.js:26:28)
    at internalTickCallback (internal/process/next_tick.js:77:7)
    at process._tickCallback (internal/process/next_tick.js:47:5)
    at Function.Module.runMain (internal/modules/cjs/loader.js:778:11)
    at startup (internal/bootstrap/node.js:300:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:826:3)
(node:19204) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:19204) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

index.js
JavaScript:
const clear = require('clear');
const ui = require('./lib/ui');
const inquirer = require('./lib/inquirer')

// clear console
clear();

// display title
ui.title();

// main execution
const run = async () => {

    clear();
    ui.title();

    while (true) {

        console.log('\n');
        const { option } = await inquirer.mainOptions();

        // clean up UI
        clear();
        ui.title();

        switch (option) {
            case 'Manage Users':
            continue;

            case 'Exit':
            process.exit();

            default:
            console.log(chalk.grey('Option not yet implemented'));
        }
    }
}

run();

inquirer.js:
JavaScript:
const inquirer = require('inquirer')

const mainOptions = async () => {
inquirer.prompt([
  {
    name: 'option',
    type: 'rawlist',
    message: 'Choose an Option:\n',
    choices: [
      'Get Total Users',
      'Manage Users',
      new inquirer.Separator(),
      'Exit'
    ]
  }
])}

module.exports = { mainOptions };

// module.exports = {mainOptions: async () =>
// inquirer.prompt([
//   {
//     name: 'option',
//     type: 'rawlist',
//     message: 'Choose an Option:\n',
//     choices: [
//       'Get Total Users',
//       'Manage Users',
//       new inquirer.Separator(),
//       'Sign Out and Exit',
//       'Exit'
//     ]
//   }
// ])}

2. Npm:llä käynnistetään node-sovellus ('npm run start'). Sovelluksen package.jsonissa on start-scriptinä 'node ./src/index.js'. Index.js:n kautta käynnistetään erillinen python-skripti python-shellillä, joka käytännössä ajaa python-skriptin lapsiprosessina (child process). Python-skripti ohjaa RaspberryPin GPIO-pinnejä. Alustana Raspbian ja kaikki ajetaan root-oikeuksin.

Kun suoritetaan 'npm run start' saadaan virheeksi
Koodi:
{ Error: /usr/local/lib/python3.7/dist-packages/sixfab_cellulariot-1.2.0-py3.7.egg/cellulariot/cellulariot.py:125: RuntimeWarning: No channels have been set up yet - nothing to clean up!  Try cleaning up at the end of your program instead!
    at PythonShell.parseError (/opt/testi/node_modules/python-shell/index.js:261:21)
    at terminateIfNeeded (/opt/testi/node_modules/python-shell/index.js:144:32)
    at ChildProcess.<anonymous> (/opt/testi/node_modules/python-shell/index.js:136:13)
    at ChildProcess.emit (events.js:198:13)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:248:12)
    ----- Python Traceback -----
    File "src/externals/testi.py", line 8, in <module>
      node.setupGPIO()
    File "/usr/local/lib/python3.7/dist-packages/sixfab_cellulariot-1.2.0-py3.7.egg/cellulariot/cellulariot.py", line 110, in setupGPIO
  RuntimeError: Not running on a RPi!
  traceback:
   'Traceback (most recent call last):\n  File "src/externals/testi.py", line 8, in <module>\n    node.setupGPIO()\n  File "/usr/local/lib/python3.7/dist-packages/sixfab_cellulariot-1.2.0-py3.7.egg/cellulariot/cellulariot.py", line 110, in setupGPIO\nRuntimeError: Not running on a RPi!\n/usr/local/lib/python3.7/dist-packages/sixfab_cellulariot-1.2.0-py3.7.egg/cellulariot/cellulariot.py:125: RuntimeWarning: No channels have been set up yet - nothing to clean up!  Try cleaning up at the end of your program instead!\n',
  executable: 'python3',
  options: null,
  script: 'src/externals/testi.py',
  args: null,
  exitCode: 1 }

Jos puolestaan python-shellille määritellään, että prosessi pitää ajaa roottina (uid: 0), niin virheenä saadaan
Koodi:
{ Error: spawn EPERM
    at ChildProcess.spawn (internal/child_process.js:366:11)
    at Object.spawn (child_process.js:551:9)
    at new PythonShell (/opt/testi/node_modules/python-shell/index.js:99:45)
    at Function.run (/opt/testi/node_modules/python-shell/index.js:214:23)
    at Promise (/opt/testi/src/utils/mode_gprs.js:6:21)
    at tryCallTwo (/opt/testi/node_modules/promise/lib/core.js:45:5)
    at doResolve (/opt/testi/node_modules/promise/lib/core.js:200:13)
    at new Promise (/opt/testi/node_modules/promise/lib/core.js:66:3)
    at changeToGprs (/opt/testi/src/utils/mode_gprs.js:5:12)
    at Object.<anonymous> (/opt/testi/src/index.js:47:1) errno: 'EPERM', code: 'EPERM', syscall: 'spawn' }

Jos sovellus ajetaan suoraan nodella 'node ./src/index.js', niin kaikki toimii niin kuin pitää. Mistä tuo nyt kiikastaa, kun npm:llä ei toimi, mutta suoraan nodella ajettuna toimii?
EDIT. package.jsonin start-skriptiin 'sudo node ./src/index.js', niin lähtee toimimaan. Kuvittelisi, että jos npm:n ajaisi roottina, niin muutkin menisivät.
 
Viimeksi muokattu:
Liittynyt
17.10.2016
Viestejä
2 190
Pari Nodeen liittyvää pikakysymystä:
1. Ajetaan sovellus tällaisenaan. Tulokseksi saadaan alla oleva virhe. Jos taas inquirer.js:n kommentoitu koodi otetaan käyttöön (ja tietenkin poistetaan 'const mainOptions...' ja ensimmäinen 'module.exports...'), sovellus toimii normaalisti. En vaan keksi, miksei tuo ensimmäinen ratkaisu toimi.
Laita nyt alkuun vaikka kaikki koodit samaan funkkariin ja lähde sen jälkeen pilkkomaan kun tiedät että toimii. Toisena vinkkinä await mielellään aina try catchin sisälle.

2. Npm:llä käynnistetään node-sovellus ('npm run start'). Sovelluksen package.jsonissa on start-scriptinä 'node ./src/index.js'. Index.js:n kautta käynnistetään erillinen python-skripti python-shellillä, joka käytännössä ajaa python-skriptin lapsiprosessina (child process). Python-skripti ohjaa RaspberryPin GPIO-pinnejä. Alustana Raspbian ja kaikki ajetaan root-oikeuksin.

Kun suoritetaan 'npm run start' saadaan virheeksi
Jos sovellus ajetaan suoraan nodella 'node ./src/index.js', niin kaikki toimii niin kuin pitää. Mistä tuo nyt kiikastaa, kun npm:llä ei toimi, mutta suoraan nodella ajettuna toimii?
Liittynee ennemmin siihen miten packaget (pip, npm) asenneltu ja onko käyttöoikeuksia tuohon GPIO, eikä varsinaisesti nodeen.
 
  • Tykkää
Reactions: Noz
Liittynyt
17.10.2016
Viestejä
7 037
En vaan keksi, miksei tuo ensimmäinen ratkaisu toimi.
Oleellinen ero on se, että ensimmäisessä et palauta mitään. Toisessa on implisiittinen return, kun et ole käärinyt nuolifunktiota aaltosulkeisiin. Eli kokeiles lisätä return inquirer.prompt:n alkuun.
 
  • Tykkää
Reactions: Noz
Liittynyt
18.10.2016
Viestejä
297
IMG_20210304_160110.jpg
Aloitteleva Pythonisti täällä, ja olen rakennellut sääasema/saunahälytintä raspin & ruuvitagien pohjalle.
Tarve olisi tehdä tarkistus onko aikajakso aikajakson sisällä, eli kun kelivaroitus tulee ennusteen mukana (kesto esim: 1615010400 - 1615068000) voimassaoloaikajaksona ja se pitäisi tarkistaa osuuko ko. sääennusteen päivälle (eli merkkaan sen varoituskolmiolla jos osuu kohdalle, kuten kuvassa). Nythän olen toteuttanut tuon sillai tyhmästi, että kun (ennuste)päivän aikaleima on sekunnilleen puoliyö ja kelivaroitusaikaleima alkaakin 01:00, niin ei liipase hälytystä ko. päivälle.
Kyseessä kelivaroitukset jotka tulevat OpenWeatherMap API:n kautta ja aikajakso unix timestamp(?) muodossa ja tämä aikaväli pitäisi tarkistaa osuuko edes osittain päivän sisään.

Koodi:
dt    1615068000    07.03.2021 0:00
wa_start_timestamp    1615010400    06.03.2021 8:00
wa_end_timestamp    1615068000    07.03.2021 0:00
Esimerkkidata ja kuva ovat samaa dataa, eli nykyisellään siis merkkaa vain tuon 7.3 koska osuu haarukkaan, vaikka se oleellsempi päivä olisi 6.3.

API:n anti:
JSON:
{
    "alerts": [
        {
            "description": "Traffic weather warning: From Saturday morning to the night between Saturday and Sunday, probability for bad road conditions is 40% because of snow or sleet.",
            "end": 1615068000,
            "event": "Traffic weather warning",
            "sender_name": "Ilmatieteen laitos",
            "start": 1615010400
        },
        {
            "description": "Traffic weather warning: From the night between Saturday and Sunday to Sunday noon, probability for bad road conditions is 30% because of snow.",
            "end": 1615118400,
            "event": "Traffic weather warning",
            "sender_name": "Ilmatieteen laitos",
            "start": 1615068000
        }
Python:
for i in range(5):
    dt = weatherdata[wthrday][0] #ennusteen päivämäärätieto, esim "7.3.2021"
    dt = datetime.datetime.strptime(dt, "%d.%m.%Y").timestamp()
    if dt >= wa_start_timestamp and dt <= wa_end_timestamp:
    wa_active_slot_[i] = True
 
Viimeksi muokattu:
Liittynyt
17.10.2016
Viestejä
7 037
@J-Man, luultavasti haluat tehdä 2 tsekkiä: osuuko ennustepäivän aikaleima 00:00 varoitushaarukan sisään ja osuuko ennustepäivän 24.00 sinne sisään. Jos edes toinen osuu, näytät varoituksen. Ehkä joku aikakirjasto osaa suoraan verrata kahta aikaväliä, jolloin helpottuu.

Tai ehkä ennusteella on aikaleima? Sitten tsekkaat onko vain se haarukan sisällä.

Ja ajan kanssa saa olla aina varuillaan, sillä aikavyöhykkeet. Eli katso että kaikki ajat varmasti ovat ns. tietoisia vyöhykkeestään.
 
Liittynyt
17.10.2016
Viestejä
2 190
Aloitteleva Pythonisti täällä, ja olen rakennellut sääasema/saunahälytintä raspin & ruuvitagien pohjalle.
Tarve olisi tehdä tarkistus onko aikajakso aikajakson sisällä, eli kun kelivaroitus tulee ennusteen mukana (kesto esim: 1615010400 - 1615068000) voimassaoloaikajaksona ja se pitäisi tarkistaa osuuko ko. sääennusteen päivälle (eli merkkaan sen varoituskolmiolla jos osuu kohdalle, kuten kuvassa). Nythän olen toteuttanut tuon sillai tyhmästi, että kun (ennuste)päivän aikaleima on sekunnilleen puoliyö ja kelivaroitusaikaleima alkaakin 01:00, niin ei liipase hälytystä ko. päivälle.
Kyseessä kelivaroitukset jotka tulevat OpenWeatherMap API:n kautta ja aikajakso unix timestamp(?) muodossa ja tämä aikaväli pitäisi tarkistaa osuuko edes osittain päivän sisään.

Koodi:
dt    1615068000    07.03.2021 0:00
wa_start_timestamp    1615010400    06.03.2021 8:00
wa_end_timestamp    1615068000    07.03.2021 0:00
Esimerkkidata ja kuva ovat samaa dataa, eli nykyisellään siis merkkaa vain tuon 7.3 koska osuu haarukkaan, vaikka se oleellsempi päivä olisi 6.3.

API:n anti:
JSON:
{
    "alerts": [
        {
            "description": "Traffic weather warning: From Saturday morning to the night between Saturday and Sunday, probability for bad road conditions is 40% because of snow or sleet.",
            "end": 1615068000,
            "event": "Traffic weather warning",
            "sender_name": "Ilmatieteen laitos",
            "start": 1615010400
        },
        {
            "description": "Traffic weather warning: From the night between Saturday and Sunday to Sunday noon, probability for bad road conditions is 30% because of snow.",
            "end": 1615118400,
            "event": "Traffic weather warning",
            "sender_name": "Ilmatieteen laitos",
            "start": 1615068000
        }
Python:
for i in range(5):
    dt = weatherdata[wthrday][0] #ennusteen päivämäärätieto, esim "7.3.2021"
    dt = datetime.datetime.strptime(dt, "%d.%m.%Y").timestamp()
    if dt >= wa_start_timestamp and dt <= wa_end_timestamp:
    wa_active_slot_[i] = True
Printtaa nuo kolme muuttujaa loopissa, dt mahtaa olla pienempi kuin start (00 vs 08). Koska tarkoituksena on vain päivämäärien vertailu ilman aikaa, on tuo unix epochien käyttö ehkä yliampuvaa ja altistaa juuri tällaisille virheille.

Pythonissa voit myös kirjoittaa tuon if lausekkeen muodossa "if start <= dt <= end".
 
Liittynyt
17.10.2016
Viestejä
2 721
Python:
for i in range(5):
    dt = weatherdata[wthrday][0] #ennusteen päivämäärätieto, esim "7.3.2021"
    dt = datetime.datetime.strptime(dt, "%d.%m.%Y").timestamp()
    if dt >= wa_start_timestamp and dt <= wa_end_timestamp:
    wa_active_slot_[i] = True
Lisää muuttuja dt2, joka seuraavan päivän aikaleima, eli dt + 24 * 60 * 60. Sitten vain katsot osuuko varoituksen alku tai loppu ko. välille.

Pseudokoodi:
Koodi:
dt2 = dt + 24 * 60 * 60
if dt <= wa_start_timestamp < dt2 or dt <= wa_end_timestamp < dt2
Itse ehkä vielä optimoisin tuota niin, että dt -> dt2 väli on jotain muuta kuin 00-24, koska onko se mielekästä näyttää päivälle varoitusta jos se päättyy klo 2 yöllä tai vastaavasti esim. alkaa vasta klo 23
 
Liittynyt
14.02.2018
Viestejä
42
Lisää muuttuja dt2, joka seuraavan päivän aikaleima, eli dt + 24 * 60 * 60. Sitten vain katsot osuuko varoituksen alku tai loppu ko. välille.

Pseudokoodi:
Koodi:
dt2 = dt + 24 * 60 * 60
if dt <= wa_start_timestamp < dt2 or dt <= wa_end_timestamp < dt2
Itse ehkä vielä optimoisin tuota niin, että dt -> dt2 väli on jotain muuta kuin 00-24, koska onko se mielekästä näyttää päivälle varoitusta jos se päättyy klo 2 yöllä tai vastaavasti esim. alkaa vasta klo 23
Tässä sama idea, toimiva toteutus. Vaihdoin tosin nuo epoch-ajat datetime -objekteiksi, koska niitä on mielestäni huomattavasti helpompi käsitellä pythonissa.


Python:
from datetime import datetime, timedelta

wa_start_timestamp = datetime.fromtimestamp(1615010400)
wa_end_timestamp = datetime.fromtimestamp(1615068000)

print(wa_start_timestamp, wa_end_timestamp)

days = [datetime(2021, 3, 5) + timedelta(days=x) for x in range(5)]

for day in days:
    dt = day
    dt2 = day + timedelta(days=1)
    print(f"Operating day: {day} - ", end="")
    if wa_start_timestamp <= dt < wa_end_timestamp or dt <= wa_start_timestamp <= dt2:
        print("Warning!")
    else:
        print("No warning")
EDIT: Bugfix, korjasin sääntöä siten, että pitkissä varoituksissa myös "välipäivät" näkyvät
 
Viimeksi muokattu:
Liittynyt
18.10.2016
Viestejä
297
Tuosta @morffi koodista varmaan saan rakennettua tarkistimen. Mutta kiitoksia kaikille ideoista, seassa on parit tipsit miten Pythonia rakennetaan. Itselläni pelkästään VBA/Excel kokemusta ja onhan se aika palikka ohjelmointikieli tämän rinnalla, tosin eipä se ole kehittynyt vuosikausiin.
 
Liittynyt
17.10.2016
Viestejä
1 187
Kiitoksia minunkin puolestani J-Man, en edes tiennyt että noita kelivaroituksia saa tuolta OpenWeatherMapin kautta vaikka se on itsellänikin käytössä ja samoin kiitoksia morffi tuosta koodista, se on "puolivalmiste" omaan ideaan/aivopieruun, ei tarvinnut itse ruveta miettimään tuota samaa asiaa että mille päiville nuo osuvat. Toisaalta heti kun näki tuon koodin niin tajusi että tuohan on itsestäänselvä juttu mutta säästipä miettimisen vaivalta :D
 
Liittynyt
17.10.2016
Viestejä
2 190
Kiitoksia minunkin puolestani J-Man, en edes tiennyt että noita kelivaroituksia saa tuolta OpenWeatherMapin kautta vaikka se on itsellänikin käytössä ja samoin kiitoksia morffi tuosta koodista, se on "puolivalmiste" omaan ideaan/aivopieruun, ei tarvinnut itse ruveta miettimään tuota samaa asiaa että mille päiville nuo osuvat. Toisaalta heti kun näki tuon koodin niin tajusi että tuohan on itsestäänselvä juttu mutta säästipä miettimisen vaivalta :D
Jos haluaa vielä ajantasaisempaa kelitietoa, kannattaa katsoa digitraffic api ;) Tieliikenne | Digitraffic - Fintraffic
 
Liittynyt
18.10.2016
Viestejä
297
Jalostelua. Eli saa valittua minimi varoituksen keston päivälle, minkä yli pitää varoitusajan mennä jotta päivämäärä merkitään varoitukseksi. Ulosanti päivämäärä-lista string muodossa.

Python:
def timerangeondates(dt_start, dt_end, minhrs=0, dateformat='%d.%m.%Y'):
    dt_start_date = datetime.datetime.fromtimestamp(dt_start)
    dt_end_date = datetime.datetime.fromtimestamp(dt_end)
    dt_start_date_zhrs = datetime.datetime(dt_start_date.year, dt_start_date.month, dt_start_date.day)
    dt_end_date_zhrs = datetime.datetime(dt_end_date.year, dt_end_date.month, dt_end_date.day)
    alert_dates = []
    days = [dt_start_date_zhrs + datetime.timedelta(days=x) for x in range((dt_end_date_zhrs - dt_start_date_zhrs).days+1)]
    #print('Start:', dt_start_date)
    #print('End:', dt_end_date)
    #print('Day Count:', (dt_end_date_zhrs - dt_start_date_zhrs).days)
    for day in days:
        if len(days) == 1:
            #print('Only one day', day)
            if (dt_end_date - dt_start_date).seconds/3600 >= minhrs:
                alert_dates.append(day.strftime(dateformat))
        elif day == days[0]:
            #print('First day', day)
            if (((datetime.datetime(day.year, day.month, day.day, 23, 59)) - dt_start_date).seconds/3600 + 1) >= minhrs:
                alert_dates.append(day.strftime(dateformat))
        elif day == days[-1]:
            #print('Last day', day)
            if (dt_end_date - dt_end_date_zhrs).seconds/3600 >= minhrs:
                alert_dates.append(day.strftime(dateformat))
        else:
            #print('Middle day', day)
            alert_dates.append(day.strftime(dateformat))
       
    return alert_dates
E: Nyt vaikuttais rokkaavan. Vajaa päivä ei menannut rekisteröityä oikein. Ei ihan nätti koodi, tuon 'ensimmäisen päivän' liipaisun olisi voinut toteuttaa lisäämällä day:hin yksi päivä, nyt on vuorokauden viimeiselle sekunnille + 1s, no jos joskus korjais paremmaksi.
 

Liitteet

Viimeksi muokattu:
Liittynyt
14.12.2016
Viestejä
29
Tekee mieli harjoitella Flaskia tai jotain muuta vastaavaa frameworkkia Pythonilla. Ajatuksena olisi tehdä RSS-lukija. Liekköhän miten työläs projekti suht aloittelijalle? Python on tuttu datan pyörittelyssä ja joitain Flask ja Django tutoriaaleja olen tehnyt. HTML+CSS kanssa tuskin on ongelmia. sekä PHP:lla olen joitain pientä rakennellut aikoinaan.

Onko kukaan tehnyt vastaavaa ja mistä tässä kannattaisi lähteä liikkeelle?
 
Liittynyt
16.11.2020
Viestejä
519
^ täällä piti toteuttaa tuollainen yliopiston palvelinohjelmoinnin vikana viikkotyönä tai jotain sinne päin. Tuossa hommassa muistaakseni hypättiin kyllä käyttään web2py:tä Flaskin sijaan, mikä oli aika ripulia, mutta muu kurssi oli Flaskilla.

Ei kai siinä mitään sen ihmeellisempää ole. XML-muotoista dataa feedistä tulee, jos asiat ei oo muuttunu muutamassa vuodessa, ja tuo data pitää vaan osata parsia ja käsitellä, eli saada olennainen informaatio datasta erilleen ja näytetyksi varsinaisen sivun lukijalle. Meillä oli muistaakseni apukirjastona minidom, mutta näyttää löytyvän joku feedparserkin ihan suoraan RSS-syötteiden lukemiseen ja parsintaan.

Liekö jonkinlainen palikkalogiikka menis seuraavasti, eli kun se sun oma sivusi ladataan, niin samassa yhteydessä luetaan halutusta syötteestä data muistiin. Sen jälkeen datalle tehdään tarvittavat taikuudet (parsinta, muotoilu ja mitä nyt tarvitaankaan) ja näytetään haluttu tavara sillä sun sivullasi. Tarkentakoon muut, ketkä enemmän tällaisten kanssa peuhaa.

muoks. XML:n käsittely tässä minusta se olennainen osattava asia.
 
Liittynyt
01.01.2018
Viestejä
432
Onko backend ja database aina eri servereillä vai miten se yleensä menee? Teen tuota fullstackopenia ja siinä tuo mongodb on eri palvelussa kokonaan kuin backend. Jotenkin kuvittelin että database tehdään aina yhdessä backendin kanssa ja ne on samassa serverissä.
 
Liittynyt
17.10.2016
Viestejä
7 037
Onko backend ja database aina eri servereillä vai miten se yleensä menee? Teen tuota fullstackopenia ja siinä tuo mongodb on eri palvelussa kokonaan kuin backend. Jotenkin kuvittelin että database tehdään aina yhdessä backendin kanssa ja ne on samassa serverissä.
Voivat olla samassa tai erissä. Aika usein halutaan pitää ne erillään, jolloin kumpaakin voidaan skaalata vapaammin ja paremmin vastaamaan tarvittavaa kuormaa. Vikasietoisuuskin saadaan näin paremmaksi kun eivät ole toisistaan riippuvaisia. Ja monissa pilvipalveluissa tietokannan saa omana erillisenä palveluna, jolloin sitä ei tarvitse itse asennella ja päivitellä.

Mutta, yhtä hyvin ne voi asentaa yhdelle ja samalle palvelimelle, jos se sopii tilanteeseen.
 
Liittynyt
17.10.2016
Viestejä
2 190
Onko backend ja database aina eri servereillä vai miten se yleensä menee? Teen tuota fullstackopenia ja siinä tuo mongodb on eri palvelussa kokonaan kuin backend. Jotenkin kuvittelin että database tehdään aina yhdessä backendin kanssa ja ne on samassa serverissä.
Ihan projektikohtaista. Nämä palveluna ostettavat db:t alkaa olla aika yleisiä, esimerkkinä nyt tuo mongodb atlas joka varmaan siinä kurssilla käytössä.
 
Liittynyt
05.11.2016
Viestejä
2 298
Onko backend ja database aina eri servereillä vai miten se yleensä menee? Teen tuota fullstackopenia ja siinä tuo mongodb on eri palvelussa kokonaan kuin backend. Jotenkin kuvittelin että database tehdään aina yhdessä backendin kanssa ja ne on samassa serverissä.
Tietokantayhteys kannattaa alusta asti hanskata siten, että on vain konfiguraatioasia siirtää tietokanta eri palvelimelle. En itse asiassa heti keksi, miten asiat saisi helposti rikottua siten, että tietokannan sijainnilla olisi jotain merkitystä.
 
Liittynyt
21.11.2016
Viestejä
249
En tiedä saako täällä kysellä kurssitehtäviin apuja, mutta pientä apua voisi kaivata, kuinka lähteä liikkeelle. Tehtävänä siis: Tiedostojen lukeminen - Ohjelmoinnin perusteet ja jatkokurssi 2021 ja tarkemmin tuo Osa 2: Pisin välimatka. Ekan osan olen saanut tehtyä.

Ymmärtääkseni tiedosto pitää loopata läpi ja laskea esim ekan rivin aseman välimatkat muihin. Mutta tässä ei vissiin yksi kierros riitä, vaan pitää sit rullata jotenkin joka rivin osalta läpi ja laskea etäisyydet?

en hae siis valmista koodinpätkää, vaan apua kuinka tässä pitäisi edetä?
 
Liittynyt
28.10.2016
Viestejä
1 731
En tiedä saako täällä kysellä kurssitehtäviin apuja, mutta pientä apua voisi kaivata, kuinka lähteä liikkeelle. Tehtävänä siis: Tiedostojen lukeminen - Ohjelmoinnin perusteet ja jatkokurssi 2021 ja tarkemmin tuo Osa 2: Pisin välimatka. Ekan osan olen saanut tehtyä.

Ymmärtääkseni tiedosto pitää loopata läpi ja laskea esim ekan rivin aseman välimatkat muihin. Mutta tässä ei vissiin yksi kierros riitä, vaan pitää sit rullata jotenkin joka rivin osalta läpi ja laskea etäisyydet?

en hae siis valmista koodinpätkää, vaan apua kuinka tässä pitäisi edetä?
Tee vaikkapa oma funktio jossa haetaan etäisyydet joka asemalle ja ne tallennetaan listaan jossa on juurikin asema1, asema2 ja etäisyys. Sitten vain haet listasta etäisyyden maksimiarvo ja palautat listasta ko. kohdan? :) Lähestymistapoja on monia.
 
Liittynyt
17.10.2016
Viestejä
7 037
En tiedä saako täällä kysellä kurssitehtäviin apuja, mutta pientä apua voisi kaivata, kuinka lähteä liikkeelle. Tehtävänä siis: Tiedostojen lukeminen - Ohjelmoinnin perusteet ja jatkokurssi 2021 ja tarkemmin tuo Osa 2: Pisin välimatka. Ekan osan olen saanut tehtyä.

Ymmärtääkseni tiedosto pitää loopata läpi ja laskea esim ekan rivin aseman välimatkat muihin. Mutta tässä ei vissiin yksi kierros riitä, vaan pitää sit rullata jotenkin joka rivin osalta läpi ja laskea etäisyydet?

en hae siis valmista koodinpätkää, vaan apua kuinka tässä pitäisi edetä?
Näissä kandee ensin tehdä yksinkertainen syöte: esim. vain 3 tai 4 asemaa. Naiivi versio ottaa aluksi ensimmäisen aseman, ja laskee etäisyydet kaikkiin muihin asemoihin, tallentaa tulokset jonnekin sitten otetaan listan toinen asema ja taas lasketaan taas etäisyydet kaikkiin muihin. Tämä tapa toimii mutta siinä lasketaan etäisyyksiä turhaan kahteen kertaan (asema 1 - asema 2, sekä asema 2 - aseman 1, vaikka ne ovat samat). Tee tämä versio ensin. Sitten mieti, miten saat tuplat hiiteen. Eli jos as1 - as2 on laskettu, ei tarvitse as2 - as1:tä laskea. Tämä onnistuu sitten ilman ehtolauseita.
 
Liittynyt
06.11.2016
Viestejä
802
Pieniä ongelmia kyseisen lausekkeen kanssa käytettäessä Typescriptiä.
JavaScript:
arr.map(item => obj[Object.keys(item)] = item[Object.keys(item)]);
Linkki kyseiseen koodinpätkään Click!

En suoraan sanottuna oikein käsitä koko virhettä.
 
Liittynyt
17.10.2016
Viestejä
7 037
En suoraan sanottuna oikein käsitä koko virhettä.
Linkki ei toimi. Ja mitä sä yrität tehdä? Anna vaikka minimaalinen toimiva esimerkki. Eli mikä on arr, mikä on obj? Object.keys() on funktio, joka palauttaa objektin propertyt taulukkona. Et voi käyttää sellaista indeksoimiseen. Mutta siis, mitä yrität tehdä?
 
Liittynyt
26.10.2016
Viestejä
718
Liittynyt
06.11.2016
Viestejä
802
Linkki ei toimi. Ja mitä sä yrität tehdä? Anna vaikka minimaalinen toimiva esimerkki. Eli mikä on arr, mikä on obj? Object.keys() on funktio, joka palauttaa objektin propertyt taulukkona. Et voi käyttää sellaista indeksoimiseen. Mutta siis, mitä yrität tehdä?
Tarkoituksena luoda taulukosta objekti, mutta olisi kiinnostanut tietää miksi Typescript lykkää virhettä tuosta ja miten se korjataan?
Ja linkki pitäisi olla toimiva.

Aika scethyn näköistä koodia, tutustuppa array.reduce. Sillä tuo hoitunee siistimmin.

Esim soveltaen tätä Quick Tip: Transform an Array into an Object using .reduce()
Pitää katsoa toi, kiitos.
 
Liittynyt
17.10.2016
Viestejä
7 037
Tarkoituksena luoda taulukosta objekti, mutta olisi kiinnostanut tietää miksi Typescript lykkää virhettä tuosta ja miten se korjataan?
Sä yrität indeksoida objektia string[]-tyypillä, eli taulukolla. Ei onnistu. Objektia indeksoidaan pelkällä stringillä, esim. obj['foo'], Eli kuten sanoin, Objekt.keys() palauttaa taulukon ja et sä sillä voi pointata yhteen objektin propertyyn.

Toiseksi, älä käytä map-funktiota jos sulle ei ole aikomus luoda uutta arrayta jota sitten käytät. Tässä tapauksessa oikea funktio, kuten sanottiin, on reduce(). Eli redusoidaan array yksittäiseksi objektiksi. Sivuvaikutuksille forEach() on myös parempi.

Kolmanneksi: mitä sä yrität tehdä? :D Eli voitko antaa yksinkertaisen esimerkin syöötteestä (se taulukko) ja mitä tuon funktion pitäisi pullauttaa ulos, eli millainen objekti pitäisi tulla? Sun siis pitää päättää, että kun sä käyt läpi sen arr:n arvoja ja laitat niitä emptyObj:iin, niin miten ne avaimet muodostetaan sille uudelle objektille? Onko ne taulukossa mukana? Eli mitä sen lopputuloksen pitäisi sun mielestäsi näyttää?

Jos se array on siis ['omena', 'appelsiini', 'banaani'], niin millainen on se objekti joka tuosta on muodostettu? Yleisesti ottaen arraysta voi tehdä objektin miljoonalla eri tavalla.
 
Viimeksi muokattu:
Liittynyt
06.11.2016
Viestejä
802
Sä yrität indeksoida objektia string[]-tyypillä, eli taulukolla. Ei onnistu. Objektia indeksoidaan pelkällä stringillä, esim. obj['foo'], Eli kuten sanoin, Objekt.keys() palauttaa taulukon ja et sä sillä voi pointata yhteen objektin propertyyn.

Toiseksi, älä käytä map-funktiota jos sulle ei ole aikomus luoda uutta arrayta jota sitten käytät. Tässä tapauksessa oikea funktio, kuten sanottiin, on reduce(). Eli redusoidaan array yksittäiseksi objektiksi. Sivuvaikutuksille forEach() on myös parempi.

Kolmanneksi: mitä sä yrität tehdä? :D Eli voitko antaa yksinkertaisen esimerkin syöötteestä (se taulukko) ja mitä tuon funktion pitäisi pullauttaa ulos, eli millainen objekti pitäisi tulla? Sun siis pitää päättää, että kun sä käyt läpi sen arr:n arvoja ja laitat niitä emptyObj:iin, niin miten ne avaimet muodostetaan sille uudelle objektille? Onko ne taulukossa mukana? Eli mitä sen lopputuloksen pitäisi sun mielestäsi näyttää?

Jos se array on siis ['omena', 'appelsiini', 'banaani'], niin millainen on se objekti joka tuosta on muodostettu?
Codepen linkki toimivaan versioon, josta selviää toivottavasti paremmin mitä yritin saavuttaa.
Tarkoituksena siis luoda taulukosta joka sisältää useita objekteja yksi objekti. Tämä sitten lisätään jo olemassa olevaan toiseen objektiin.
 
Liittynyt
17.10.2016
Viestejä
7 037
Codepen linkki toimivaan versioon, josta selviää toivottavasti paremmin mitä yritin saavuttaa.
Tarkoituksena siis luoda taulukosta joka sisältää useita objekteja yksi objekti. Tämä sitten lisätään jo olemassa olevaan toiseen objektiin.
Eli sulla on lista objekteja, ja haluat redusoida ne yhdeksi objektiksi?

Jotain tällaista siis?

JavaScript:
type Obj = {[key: string]: {[key: string]: string}};
type Foo = Array<Obj>;

const foo: Foo = [{foo: {a: '1'}}, {bar: {a: '2'}}, {foo: {a: '3'}}];
const obj = foo.reduce((acc, cur) => Object.assign(acc, cur), {});

console.log({obj});
Huomaa, että taulukon kolmas alkio ylikirjoitti ekan tarkoituksella. Lisäsin myös vähän tyyppejä, sillä ne helpottavat homman hahmottamista ja blokkaavat virheitä. Muuta tarpeeseen. Oliko tämä, mitä hait takaa? Joku lodash sisältää muuten paljon objektien ja taulukoiden käpistelyyn tarkoitettuja pikku apufunktioita. Suosittelen kokeilemaan.
 
Viimeksi muokattu:
Liittynyt
06.11.2016
Viestejä
802
Eli sulla on lista objekteja, ja haluat redusoida ne yhdeksi objektiksi?

Jotain tällaista siis?

JavaScript:
type Obj = {[key: string]: {[key: string]: string}};
type Foo = Array<Obj>;

const foo: Foo = [{foo: {a: '1'}}, {bar: {a: '2'}}, {foo: {a: '3'}}];
const obj = foo.reduce((curr, next) => Object.assign(curr, next), {});

console.log({obj});
Huomaa, että taulukon kolmas alkio ylikirjoitti ekan tarkoituksella. Lisäsin myös vähän tyyppejä, sillä ne helpottavat homman hahmottamista ja blokkaavat virheitä. Muuta tarpeeseen. Oliko tämä, mitä hait takaa? Joku lodash sisältää muuten paljon objektien ja taulukoiden käpistelyyn tarkoitettuja pikku apufunktioita. Suosittelen kokeilemaan.
Kyllä.
Taulukko (esimerkissä olevat kielet) mapataan objekteiksi, mutta koska näistä muodostuu taulukko(data muuttuja), niin nämä täytyy muuttaa yhdeksi objektiksi, joka lisätään jo olemassa olevaan toiseen objektiin (tabs).

Mutta tuo esimerkki näyttäisi olevan juuri sitä mitä hain, kiitos!
 
Liittynyt
26.10.2016
Viestejä
718
Kyllä.
Taulukko (esimerkissä olevat kielet) mapataan objekteiksi, mutta koska näistä muodostuu taulukko(data muuttuja), niin nämä täytyy muuttaa yhdeksi objektiksi, joka lisätään jo olemassa olevaan toiseen objektiin (tabs).

Mutta tuo esimerkki näyttäisi olevan juuri sitä mitä hain, kiitos!
Reduce Typescriptissä pitää tyypittää, tässä kompakti (TS) versio tuosta sun taskista.
JavaScript:
const languages = ['fi', 'en'];

interface Result {
    id: number;
    paragraphs: Array<any>;
    translations?: {
        [lang:string]:{
            'value': string
        }
    };
}
const tabs = {
  id: 123,
  paragraphs: []
};
const objectFromEntries = languages.reduce<Result>((acc,cur) => {
  return {...acc, translations: {
        ...acc.translations, [cur]: {'value': `value ${cur}`}
        }
    }
},tabs);

console.log(objectFromEntries);
 
Viimeksi muokattu:
Toggle Sidebar

Uusimmat viestit

Statistiikka

Viestiketjut
124 781
Viestejä
2 436 514
Jäsenet
49 073
Uusin jäsen
Antero10

Hinta.fi

Ylös Bottom