Pieniä kysymyksiä ohjelmoinnista

Liittynyt
17.10.2016
Viestejä
443
Onko tällaisista intensiivikursseista mitään apua jos lähtee ns. nollista liikkeelle esim. alan vaihtoa suunnittelevalle?


Mainospuheet ainakin ovat hienot mutta miten todellisuus?
 
Liittynyt
17.10.2016
Viestejä
5 331
Kyllä tuosta varmaan saa ainakin jotain irti mutta ei tuollainen kurssi mitään valmista koodaria tee. Tietty jos on motivoitunut ja jaksaa vapaa-ajalla koodailla lisäksi niin kyllähän tuo varmaan auttaa aika paljon alkuun.

Koodaus kuitenkaan ei ole pelkästään jonkun ohjelmointikielen (syntaksin) osaamista vaan pitää osata soveltaa ja pikemminkin pitää osata ajatella niin että osaa ratkaista ongelmia halutulla ohjelmointikielellä.
 
Liittynyt
28.07.2020
Viestejä
330
Onko tällaisista intensiivikursseista mitään apua jos lähtee ns. nollista liikkeelle esim. alan vaihtoa suunnittelevalle?


Mainospuheet ainakin ovat hienot mutta miten todellisuus?
Kyllähän tuosta nyt jotain pikku helppiä saattaa olla, mutta suurin apu on siitä kuinka motivoitunut on oppimaan/opiskelemaan itsenäisesti. Lähtökohtaisesti koulu/koulutukset (omasta mielestäni) on paperinpala mustaavalkosella että "Osaa" jonkun asian ja on "kykenevä" siihen. Nykypäivänä lähes mitä vain voi oppia itsenäisesti koska internetti on täynnä videoita ja ohjeita (hyviä että huonoja) ja tätä ehtymätöntä tietolähdettä kun käyttää oikein niin anti on huomattasti suurempaa kuin yhdessäkään koulussa/koulutuksessa.
 
Liittynyt
18.10.2016
Viestejä
69
Onko tällaisista intensiivikursseista mitään apua jos lähtee ns. nollista liikkeelle esim. alan vaihtoa suunnittelevalle?


Mainospuheet ainakin ovat hienot mutta miten todellisuus?
Helsingin avoimen yliopiston kurssitarjonta on ehkä jo sinulle tuttua mutta sieltäkin löytyy hyvä valikoima verkkokursseja, joilla pääsee pitkälle.

Itse toteutin samanlaisen alanvaihdon niin että tein töiden ohessa kaikki avoimessa tarjolla olevat TKT-opinnot ja hain sitten myös tutkinto-opiskelijaksi, niin sain vielä lisää kursseja tarjolle. Vuoden kuluttua aloittamisesta koin, että voisin koittaa hakea töitä, ja sainkin sitten paikan – mielestäni yllättävänkin helposti.

Jokaisen tilanne ja aiempi kokemus on tietysti erilainen, mutta tuollainen polku toimi ainakin minun kohdallani. Toki päivätöiden ohessa opiskelu vaatii aikaa mutta toisaalta hyvä motivaatio auttaa paljon. Yksi hyvä juttu on että käytännössä kaikki onnistuu verkossa, ja yliopistolla olen tainnut käydä vain kahdesti tenttiä tekemässä.
 
Liittynyt
28.08.2018
Viestejä
81
React + Redux aiheinen kysymys. Jos importtaa komponenttiin actioneistä sen funktion, jolla haetaan dataa rajapinnasta ja Reactin hooksejä hyödytäen kutsuu em. funktiota dispatchin kautta useEffectissä. Se toimii kyllä, mutta onko tuo huono tapa? Jos on, niin mielelläni luen vinkkejä siitä miten tuo tehdään paremmin. Alla pätkä koodia.

JavaScript:
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { getData } from '../actions/index';

const Users = () => {
    const users = useSelector(state => state.users);
    const dispatch = useDispatch();
    
    useEffect(() => {
        dispatch(getData())
    }, [])
}
 
Liittynyt
13.11.2016
Viestejä
1 512
Toteutus on validi, varsinainen virhe olisi lähettää tuo action jossain muualla kuin effectin sisällä (ns. render-funktiossa). Itselläni on ollut tapana connectata komponentit omassa container-komponentissa jolloin niiden varsinaisten viewien unit-testaaminen on suoraviivaisempaa - varsinkin tapauksissa joissa näkymä rakennetaan monimutkaisen staten perusteella niin nuo containerit voivat sisältää ihan jonkin verran logiikkaakin ja näkymät pysyvät siistinä.
 
  • Tykkää
Reactions: hmb
Liittynyt
17.10.2016
Viestejä
14 550
Jos on, niin mielelläni luen vinkkejä siitä miten tuo tehdään paremmin.
Kyllä noin voi tehdä. Yksi tapa siistiä koodia on bindata ne actionit valmiiksi, jolloin joka komponentissa ei tarvitse erikseen käyttää dispatch()-kutsua, vaan voit suoraan käskyttää getData(), joka pitää sisällään dispatchauksen.
 
Liittynyt
01.02.2017
Viestejä
747
Mitens, kun pitäisi saada csv-tiedostosta tullut päivämäärä muodossa 20200803 sellaiseen muotoon että Google Sheets sen ymmärtäisi päivämääräksi? Pitäisikö sitä vaan alkaa tehdä jotain himmeliä MID() funktionilla eli leikkailla ja liimailla vai näkeekö joku ratkaisun nopeammin. Tietenkin REGEX on vastaus kaikeen, mutta aika käsi niissä. Yksi vaihtoehto voisi tietenkin tehdä App Script koodia (joka lieni melkein sama kuin JS) joka muutoksen tekisi, vai?
 
Liittynyt
17.10.2016
Viestejä
5 658
Mitens, kun pitäisi saada csv-tiedostosta tullut päivämäärä muodossa 20200803 sellaiseen muotoon että Google Sheets sen ymmärtäisi päivämääräksi? Pitäisikö sitä vaan alkaa tehdä jotain himmeliä MID() funktionilla eli leikkailla ja liimailla vai näkeekö joku ratkaisun nopeammin. Tietenkin REGEX on vastaus kaikeen, mutta aika käsi niissä. Yksi vaihtoehto voisi tietenkin tehdä App Script koodia (joka lieni melkein sama kuin JS) joka muutoksen tekisi, vai?
Aika simppelillä kaavalla tuosta selviää:
=DATE(LEFT(A1,4), MID(A1,5,2), RIGHT(A1,2))
 
Liittynyt
01.02.2017
Viestejä
747
Aika simppelillä kaavalla tuosta selviää:
=DATE(LEFT(A1,4), MID(A1,5,2), RIGHT(A1,2))
Erinomaisesti kiitos. Ehkä sadanvuoden kuluttua olisin päätynyt samaan. Miksiköhän muuten mun GS ei hyväksy pilkkuja, vaan pitää pistää puolipiste? Onko se koska GS:ni on suomeksi? Ilmeisesti menisi valuuttojen kanssa sekaisin.
 
Liittynyt
17.10.2016
Viestejä
5 658
Erinomaisesti kiitos. Ehkä sadanvuoden kuluttua olisin päätynyt samaan. Miksiköhän muuten mun GS ei hyväksy pilkkuja, vaan pitää pistää puolipiste? Onko se koska GS:ni on suomeksi? Ilmeisesti menisi valuuttojen kanssa sekaisin.
Joo, lokalisointijuttu. Voit File -> Spreadsheet Settings (tai siis suomeksi jotain vastaavaa tietty...) mennä ja vaihtaa lokalisointia jos huvittaa. Itse tottunut käyttämään englanniksi kaikkia niin tuo tosiaan jenkkilokalisaatiolle.
 
Liittynyt
03.07.2018
Viestejä
347
haluaisin python-ohjelman nettiin. privaatti api-tyyppinen ratkaisu joka ottaa vastaan get /post ja palauttaa stringin.

miten pythonia hostataan, ilmeisesti pitää olla ngix proxynä edessä?
mistä tämmösen palvelimen/palvelun saa hyvällä hintalaatusuhteella?
 
Liittynyt
17.10.2016
Viestejä
5 658
haluaisin python-ohjelman nettiin. privaatti api-tyyppinen ratkaisu joka ottaa vastaan get /post ja palauttaa stringin.

miten pythonia hostataan, ilmeisesti pitää olla ngix proxynä edessä?
mistä tämmösen palvelimen/palvelun saa hyvällä hintalaatusuhteella?
Riippuu vähän mitä se sun ohjelmasi tekee ja kuinka usein sitä kutsutaan. Jos jotain hyvin yksinkertaista niin suosittelen tutustumaan esimerkiksi Azure Functionsiin. Azuren ilmaistieriin kuuluu miljoona kyselyä per kuukausi (hintaan 0e), eli hintalaatusuhde lienee riittävähkö. Jos sitten ohjelmasi tekee jotain monimutkaisempaa niin riippuu vähän että mitä kaikkea siellä taustalla rullailee... Onko ohjelmasi output pelkästään riippuvainen siitä GET/POST requestin datasta, vai lukeeko se lisäksi esim. jotain tietokantaa tai tiedostoja jostain?

Rajapintakikkailuun Pythonilla suosittelen FastAPIa. Se on vähän kuin Flask steroideilla ja upealla dokumentaatiolla.
 
Viimeksi muokattu:
Liittynyt
03.07.2018
Viestejä
347
Riippuu vähän mitä se sun ohjelmasi tekee ja kuinka usein sitä kutsutaan. Jos jotain hyvin yksinkertaista niin suosittelen tutustumaan esimerkiksi Azure Functionsiin. Azuren ilmaistieriin kuuluu miljoona kyselyä per kuukausi (hintaan 0e), eli hintalaatusuhde lienee riittävähkö. Jos sitten ohjelmasi tekee jotain monimutkaisempaa niin riippuu vähän että mitä kaikkea siellä taustalla rullailee... Onko ohjelmasi output pelkästään riippuvainen siitä GET/POST requestin datasta, vai lukeeko se lisäksi esim. jotain tietokantaa tai tiedostoja jostain?

Rajapintakikkailuun Pythonilla suosittelen FastAPIa. Se on vähän kuin Flask steroideilla ja upealla dokumentaatiolla.
Tietokantaa ei tarvitsisi tuossa olla, mutta jonkinlainen yhteys tiedostoihin.
Tarkoitus olisi siis käsitellä äänitiedostoja pythonilla, esim. jostain googlen cloud storagesta ja palauttaa sitten vaan linkki takaisin... toki se muokattu äänitiedostokin pitää tallentaa sinne cloudiin takaisin, eli raskasta käsittelyä, mutta ei varmastikkaan ole kovin suosittu palvelu aluksi..
 
Liittynyt
03.07.2018
Viestejä
347
Miten vue.js:ssä saa child-komponentilta tulevan ajax-datan välitettyä "viereiselle" komponentille niin että mahdollisimman paljon säästyisi muistia ?
Nyt se toimii emitillä parenttiin jossa se kopioidaan toisen childin propsiin ja sielä on taas computed joka ainoastaan tsekkaa ettei data ole null.

Tämä toimii, mutta tuntuu tyhmältä. Vuexia ei näin pienessä softassa kuitenkaan kannata käyttää. Tuo data päivittyy helposti useasti ja ja on luokkaa usempi kilotavu...mikäli sillä on mitään merkitystä
 
Liittynyt
14.02.2018
Viestejä
73
Tietokantaa ei tarvitsisi tuossa olla, mutta jonkinlainen yhteys tiedostoihin.
Tarkoitus olisi siis käsitellä äänitiedostoja pythonilla, esim. jostain googlen cloud storagesta ja palauttaa sitten vaan linkki takaisin... toki se muokattu äänitiedostokin pitää tallentaa sinne cloudiin takaisin, eli raskasta käsittelyä, mutta ei varmastikkaan ole kovin suosittu palvelu aluksi..
Myös Amazonin Lambda sopii tuohon aika hyvin. Ylipäänsä mikä tahansa näistä kolmesta isosta (AWS/Google/Azure) toimii hyvin, enemmän kyse lienee siitä, mitä palvelua haluaa alkaa opetella käyttämään.

Esim AWS lambdan kanssa erillistä nginx-proxyä ei välttämättä tarvita, jos käyttää AWS:n API Gatewaytä.
 
Liittynyt
17.10.2016
Viestejä
479
Mulla on ongelma node.js exporttauksen kanssa. Frameworkkina on Express ja oon käyttänyt semmoista oletusbuildia, joka on luonut aloitustiedostoja. Yksi päätiedostoista on www.js niminen tiedosto, joka mm. hoitaa serverin luomisen, joka tallennetaan server nimiseen muuttujaan.

Mulla on Socket.IO käytössä ja koko socket logiikka on kirjoitettuna www.js filuun toistaiseksi. Käytännössä yhdistäminen on näin:

Java:
var io = require('socket.io')(server);

const nsp = io.of('/rakennusc/1/keittiö');
nsp.on('connection', function(socket){
  console.log('Client connected ');
Haluaisin kuitenkin kaikki socket-koodit erilliseen filuun. Esim. SocketIOConnections.js. Mulla on ongelmia saada tuota server muuttujaa joka tuossa socketissa vaaditaan siirrettyä uuteen filuun.

Koitin exporttaa serverin
Koodi:
exports.server = server
ja sitten tuossa custom filussa requiraa se
Koodi:
const www = require("../bin/www");
Kuitenkin jos luon tuon socket yhteyden ja käytän server kohdalla
Koodi:
var io = require('socket.io')(www.server);
niin mitään ei tapahdu. Virhettä ei tule, mutta sockettiin ei saa yhteyttä. Kuinkahan saisin nuo socket logiikat eri filuun?

Edit: Nyt kun tarkemmin ajattelen niin eihän tässä ole vielä mitään, joka tuota filua kutsuu joten sen logiikkaa ei ajeta, joka sekoittaa pakkaa entisestään. Miten ihmeessä mä saan tämän toimimaan kun tuo www.js filu on filu, joka ajetaan ihan logiikan alussa.
 
Liittynyt
17.10.2016
Viestejä
4 589
Miksi et tee niin päin, että sieltä SocketIOConnections.js exportataan se mitä tarvitaan socketin käynnistämiseen (esim. yksi funktio joka ottaa sen serverin parametrinä) ja sitä kutsutaan tuolla serverin starttaavassa www.js:ssä?
 
Liittynyt
17.10.2016
Viestejä
479
Miksi et tee niin päin, että sieltä SocketIOConnections.js exportataan se mitä tarvitaan socketin käynnistämiseen (esim. yksi funktio joka ottaa sen serverin parametrinä) ja sitä kutsutaan tuolla serverin starttaavassa www.js:ssä?
Kiitti. Hmm, kuulostaa järkevältä, mutta en nyt oikein hoksaa kuinka asia tehtäisiin. Kuinka siis exporttaisin tuon funktion kun sitä ei ole vielä luotu mihinkään? Kuinka muu logiikka toimii yhteen sen kanssa, että exportattu muuttuja käynnistetään www.js filussa?
 
Liittynyt
19.10.2016
Viestejä
1 916
Kävin jo excel-ketjussa kyselemässä vähän apuja ja nyt oivalsin, että kysymäni asia yksinkertaistuisi vielä entisestään jos seuraava onnistuisi..

- minulla on vbs tiedosto, jonka ajan kansiossa komennolla: cscript //NoLogo fetchstats.vbs xxxxxxxxxx xxxxxxxxxx 2020-09-05 >05.09.2020.csv
- vbs generoi raportin kyseiseltä päivältä, ja luo file_05.09.2020.csv -tiedoston.
- tämä filu menee sitten exceliin jatkofiltteröintiin ja käsittelyyn

Onko mitenkään mahdollista luoda jotakin battia yms. joka ajaisi cscript komennon, mutta komennon 2020-09-05 ja 05.09.2020.csv nimet muuttuisivat aina kyseistä päivämäärää vastaamaan milloin komento ajetaan?
esim. jos tänään klikkaisin battia, niin script-lause olisi:
cscript //NoLogo fetchstats.vbs xxxxxxxxxx xxxxxxxxxx 2020-09-10 >10.09.2020.csv
 
Liittynyt
18.10.2016
Viestejä
505
Kävin jo excel-ketjussa kyselemässä vähän apuja ja nyt oivalsin, että kysymäni asia yksinkertaistuisi vielä entisestään jos seuraava onnistuisi..

- minulla on vbs tiedosto, jonka ajan kansiossa komennolla: cscript //NoLogo fetchstats.vbs xxxxxxxxxx xxxxxxxxxx 2020-09-05 >05.09.2020.csv
- vbs generoi raportin kyseiseltä päivältä, ja luo file_05.09.2020.csv -tiedoston.
- tämä filu menee sitten exceliin jatkofiltteröintiin ja käsittelyyn

Onko mitenkään mahdollista luoda jotakin battia yms. joka ajaisi cscript komennon, mutta komennon 2020-09-05 ja 05.09.2020.csv nimet muuttuisivat aina kyseistä päivämäärää vastaamaan milloin komento ajetaan?
esim. jos tänään klikkaisin battia, niin script-lause olisi:
cscript //NoLogo fetchstats.vbs xxxxxxxxxx xxxxxxxxxx 2020-09-10 >10.09.2020.csv
Koodi:
@echo off
setlocal
for /f "tokens=2-4 delims=. " %%a in ('date /t') do (set paev=%%c-%%b-%%a& set tied=%%a.%%b.%%c.csv)
echo %paev% %tied%
Tuon pohjalta päässee eteenpäin. Huhujen mukaan Powershell tekee tämän paremmin ja helpommin, mutta se jätetään lukijalle harjoitukseksi.
 
Liittynyt
17.01.2018
Viestejä
1 997
Ainakin ennen, varmaan nytkin date- komennon tulostusmuoto riippuu käyttäjän maa- asetuksista, sen käyttö on ehkä hieman riskialtista.

Tämä toimii jokaisessa samalla tavalla riippumatta käyttiksen kielestä tai käyttäjän maa-asetuksista:
Koodi:
@ECHO OFF

for /f "usebackq tokens=1,2 delims=,=- " %%i in (`wmic os get LocalDateTime /value`) do (
    @if %%i==LocalDateTime (
        set FULLDATETIME=%%j
    )
)
SET YEAR=%FULLDATETIME:~0,4%
SET MONTH=%FULLDATETIME:~4,2%
SET DAY=%FULLDATETIME:~6,2%

SET PVM=%YEAR%-%MONTH%-%DAY%
SET FILENAME=%PVM%.csv

cscript /NoLogo fetchstats.vbs xxxxxxxxxx xxxxxxxxxx %PVM% > %FILENAME%
 
Liittynyt
17.10.2016
Viestejä
4 589
Kiitti. Hmm, kuulostaa järkevältä, mutta en nyt oikein hoksaa kuinka asia tehtäisiin. Kuinka siis exporttaisin tuon funktion kun sitä ei ole vielä luotu mihinkään? Kuinka muu logiikka toimii yhteen sen kanssa, että exportattu muuttuja käynnistetään www.js filussa?
En tiedä saitko jo toimimaan, mutta tarkoitin siis jotain tällaista:

JavaScript:
// MySocket.js

const socketIo = require("socket.io");

function MySocket(server) {
   
    const io = socketIo(server);

    const nsp = io.of("/rakennusc/1/keittiö");
    nsp.on("connection", function (socket) {
        console.log("Client connected ");
    });

    // Muut socket koodit
}

module.exports = MySocket;

// -------------------------------------------------------------------------------
// www.js

const express = require("express");
const mySocket = require("MySocket.js");

const app = express();
const server = app.listen(5000);

const socket = mySocket(server);

//...
 
Liittynyt
14.10.2017
Viestejä
620
Kysymys yksikkötestauksesta ja siihen liittyvästä koodin faktoroinnista. Asia liittyy läheisesti tähän SO:n kysymykseen ja erityisesti tämä kommentti kiteyttää huolenaiheeni.

Oletetaan, että jokin ulkopuolinen taho (esim. asiakasyritys) tarjoaa kirjaston tai API:n, jonka ainoa sisältö on Downloader-luokka, jonka julkiseen rajapintaan kuuluu ainoastaan download-funktio. Tämä funktio ottaa argumentikseen listan tiedostotunnisteita ja palauttaa yhden taulukon tai objektin, johon nämä pyydetyt tiedostot on jotenkin koottu. Oletetaan, että palautetusta objektista on aina mahdollista erotella yksittäisten tiedostojen sisällöt, joskaan loppukäyttäjä ei tällaisesta erottelusta ole kiinnostunut. Voidaan vaikka ajatella, että D=Downloader(); D.download(["kissa", "koira"]); palauttaa kuvan, jossa on kissan ja koiran kuvat laitettu peräkkäin yhdeksi isoksi kuvaksi.

Downloader on äärimmäisen hidas, kallis ja huono, eikä muokattavissa. Samat tiedostotunnisteet toistuu usein kun download-funktiota kutsutaan, joten helpotan tilannetta koodaamalla välimuistia hyödyntävän FastReader-luokan. Tämän luokan julkinen rajapinta koostuu read-funktiosta, jonka input ja output on täsmälleen samat kuin em. download-funktiossa. Pseudokoodi voisi näyttää vaikka tältä:
Koodi:
function read(list):
    N = length(list);
    images = image_array(N);
   
    for index in 1...N:
        if list[index] is in self.cache:
            images[index] = self.read_cache(list[index]);
            list.erase(index);
        end if
    end for
   
    if list is not empty:
        if self.D is uninitialized
            self.D = Downloader(); # only when necessary
        end if
        remote_data = self.D.download(list);
        remote_images = self.split_images(remote_data);
        self.write_cache(list, remote_images);
        images.replace_uninitialized_values(remote_images);
    end if
   
    return self.merge_images(images);
Ja yksikkötestaus voisi näyttää tältä:
Koodi:
function test_not_in_cache():
    FR = FastReader();
    result = FR.read(["kissa", "koira"]);
    assertSameImage(result, "kissakoira.jpg"]);
   
function test_exists_in_cache():
    FR = FastReader();
    result1 = FR.read(["kissa", "koira"]);
    result2 = FR.read(["kissa", "koira"]);
    assertSameImage(result2, "kissakoira.jpg"]);
   
function test_partial_cache():
    FR = FastReader();
    result1 = FR.read(["kissa", "kala"]);
    result2 = FR.read(["kissa", "koira"]);
    assertSameImage(result2, "kissakoira.jpg"]);
Yksikkötestauksen ongelmana on, että Downloader-konstruktorin kutsu maksaa miljoona dollaria, eikä kaikilla FastReader-luokan kehittäjillä välttämättä ole Downloaderia käytössä lainkaan. Toisaalta kissan, koiran ja kalan tapauksessa kuvat tiedetään, joten olisi helppoa tehdä DownloaderMock-luokka, johon on hard-koodattu nämä kolme eläintä ja jota voisi siten hyödyntää FastReader-luokan yksikkötestauksessa. Mutta siitä päästäänkin tuohon SO:n ongelmaan, eli mock-luokkaa (en tiedä mitä on suomeksi) ei tässä voikaan käyttää, koska D on FastReaderin private-muuttuja. Keksin kyllä purkkaratkaisuja (esim. käyttää jotain kielikohtaisia erikoisominaisuuksia, tai sitten nimeää mock-luokan identtisesti varsinaisen luokan kanssa ja muuttaa testauksen ajaksi kirjastojen hakupolkuja siten, että mock-luokka "peittää" oikean luokan), mutta ne ei tunnu oikeilta.

Missä kohtaa suunnittelu meni pieleen?
 
Liittynyt
14.02.2018
Viestejä
73
Mutta siitä päästäänkin tuohon SO:n ongelmaan, eli mock-luokkaa (en tiedä mitä on suomeksi) ei tässä voikaan käyttää, koska D on FastReaderin private-muuttuja. Keksin kyllä purkkaratkaisuja (esim. käyttää jotain kielikohtaisia erikoisominaisuuksia, tai sitten nimeää mock-luokan identtisesti varsinaisen luokan kanssa ja muuttaa testauksen ajaksi kirjastojen hakupolkuja siten, että mock-luokka "peittää" oikean luokan), mutta ne ei tunnu oikeilta.
Itse lähtisin refaktoroimaan tuota siten, että jakaisin funktion FastReader.read -funktion kahtia. Ensimmäinen osa lataisi aineiston cachesta (read_cached), ja toinen sitten (tarvittaessa) alkuperäisestä lähteestä (read_original). Nyt siis riittää, että mockaat tuon read_original -funktion, jolloin kyselyt eivät koskaan mene Downloader() -luokalle, mutta voit edelleen testata read_cached -funktiota normaalisti.

Itsellä loppuu java-taidot tuon read_original -funktion testaamiseksi (pythonilla käyttäisin joko pytest-monkeypatchia, jolloin mockaisin Downloader-luokan importin jälkeen, tai requests_mock-kirjastoa, joka kaappaisi Downloader-luokan tekemät HTTP-kutsut).

Java:
class FastReader:
    function read_cached(list):
        N = length(list);
        images = image_array(N); 
        for index in 1...N:
            if list[index] is in self.cache:
                images[index] = self.read_cache(list[index]);
                list.erase(index);
            end if
        end for

        if list is not empty:
            remote_images = self.read_original(list) 
            images.replace_uninitialized_values(remote_images);
        end if
        return self.merge_images(images);
        
    function read_original(list):
        if self.D is uninitialized
               self.D = Downloader(); # only when necessary
          end if
        remote_data = self.D.download(list);
         remote_images = self.split_images(remote_data);
           self.write_cache(list, remote_images);
           return remote_images
 
Liittynyt
27.04.2017
Viestejä
31
Vaihtoehtoisena ajatuksena jonkinlainen object factory. Eli fastreader ei kutsu suoraan downloader-luokan konstruktoria vaan käyttää jotain interfacea, mikä esittelee download-metodin. Interfacen toteuttava instanssi kysytään factoryltä.
Factorylle kerrotaan sitten ennen testien suorittamista, että mikä luokka toteuttaa halutun interfacen eli testeissä sinne rekisteröidään joku mock-downloader ja tuotantokoodissa ulkopuolinen kirjasto. Näin ollen tuota fastreader-luokan koodia ei tarvi muokata vaan se käyttää aina pelkkää interfacea ja interfacen toteuttaja hoitaa loput.
 
Liittynyt
14.10.2017
Viestejä
620
Itse lähtisin refaktoroimaan tuota siten, että jakaisin funktion FastReader.read -funktion kahtia. Ensimmäinen osa lataisi aineiston cachesta (read_cached), ja toinen sitten (tarvittaessa) alkuperäisestä lähteestä (read_original). Nyt siis riittää, että mockaat tuon read_original -funktion, jolloin kyselyt eivät koskaan mene Downloader() -luokalle, mutta voit edelleen testata read_cached -funktiota normaalisti.
En tullutkaan ajatelleeksi, että testattavaa luokkaa voisi mockata. Siis sitä osaa luokasta, jota ei testata. Toteutetaanko tuo käytännössä niin, että teen FastReaderMock-luokan, joka perii FastReader-luokan, ja FastReaderMockissa määrittellään read_original-funktio uudestaan? Yksikkötestaus kohdistuisi sitten FastReaderMockiin. Testaus on mielekästä, koska perintä takaa sen, että luokat toimivat identtisesti lukuun ottamatta tuota read_original-funktiota. Ainut "ongelma" on se, että read_original ei voi olla private, joskin se voisi kuitenkin olla protected. Periaatteessahan tätä lähestymistapaa voisi käyttää esittämääni refaktoroimattomaankin versioon. Eli jos D-muuttajasta tekee protectedin, niin FastReaderMockista voisi tehdä sellaisen, että D:hen laitetaankin DownloaderMock-luokan objekti. Nyt pitäisi siis tehdä kaksi mock-luokkaa.

Vaihtoehtoisena ajatuksena jonkinlainen object factory. Eli fastreader ei kutsu suoraan downloader-luokan konstruktoria vaan käyttää jotain interfacea, mikä esittelee download-metodin. Interfacen toteuttava instanssi kysytään factoryltä.
Factorylle kerrotaan sitten ennen testien suorittamista, että mikä luokka toteuttaa halutun interfacen eli testeissä sinne rekisteröidään joku mock-downloader ja tuotantokoodissa ulkopuolinen kirjasto. Näin ollen tuota fastreader-luokan koodia ei tarvi muokata vaan se käyttää aina pelkkää interfacea ja interfacen toteuttaja hoitaa loput.
Toteutaanko tämä käytännössä niin, että DownloaderObjectFactory-luokalla on jokin staattinen muuttuja, joka määrittelee minkälainen object palautetaan seuraavaksi? Eli jotenkin näin (iso alkukirjain viittaa luokkaan eikä mihinkään instanssiin):
Koodi:
function test_FastReader():
    DownloaderObjectFactory.nextInstanceType = "mock";
    FR = FastReader();
    # testausta
    DownloaderObjectFactory.nextInstanceType = "normal";
Ja FastReaderissa kutsutaan kaikissa tilanteissa DownloaderObjectFactory.getDownloader() ilman mitään argumentteja.
 
Liittynyt
19.10.2016
Viestejä
1 916
Ainakin ennen, varmaan nytkin date- komennon tulostusmuoto riippuu käyttäjän maa- asetuksista, sen käyttö on ehkä hieman riskialtista.

Tämä toimii jokaisessa samalla tavalla riippumatta käyttiksen kielestä tai käyttäjän maa-asetuksista:
Koodi:
@ECHO OFF

for /f "usebackq tokens=1,2 delims=,=- " %%i in (`wmic os get LocalDateTime /value`) do (
    @if %%i==LocalDateTime (
        set FULLDATETIME=%%j
    )
)
SET YEAR=%FULLDATETIME:~0,4%
SET MONTH=%FULLDATETIME:~4,2%
SET DAY=%FULLDATETIME:~6,2%

SET PVM=%YEAR%-%MONTH%-%DAY%
SET FILENAME=%PVM%.csv

cscript /NoLogo fetchstats.vbs xxxxxxxxxx xxxxxxxxxx %PVM% > %FILENAME%
Piti jo aiemmin laittaa kiitosta tästä, mutta en näemmä ollut laittanut. Eli kiitos. Tämä toimii hienosti.

EDIT: jatkokysymys. Miten tuohon scriptiin lisätään salasana mukaan. Eli kun ajan tuon scriptin, niin se kysäisee cmd:ssä seuraavaksi salasanaa. Voiko cscript lauseeseen lisätä salasanan jotenkin?
 
Viimeksi muokattu:
Liittynyt
17.01.2018
Viestejä
1 997
Piti jo aiemmin laittaa kiitosta tästä, mutta en näemmä ollut laittanut. Eli kiitos. Tämä toimii hienosti.

EDIT: jatkokysymys. Miten tuohon scriptiin lisätään salasana mukaan. Eli kun ajan tuon scriptin, niin se kysäisee cmd:ssä seuraavaksi salasanaa. Voiko cscript lauseeseen lisätä salasanan jotenkin?
Riippuu siitä mikä kyselee ja miten. Jos sen joutuu kirjoittamaan terminaaliin niin voi olla että joutuu tekemään tyyliin

echo salasana | cscript jne

ja kyselijästä riippuen toimii tai ei...
Paras olisi jos sille csriptille voisi antaa salasanan parametrina mutta näkemättä toteutusta ei oikein pysty arvaamaan miten se on tehty
 
Liittynyt
28.01.2017
Viestejä
469
nimetön.png

Miten tämän tehtävän osa 2 tehdään Pythonissa? Nimimerkillä amatööri.

EDIT: Inputtia saa kysyä vain kerran. Ajatuksena siis käyttää while True:
 
Liittynyt
28.01.2017
Viestejä
469
if input sama kuin loppu tai sama kuin edellinensana varmaan toiminee
Saako tästä vielä sellaisen rautalankaversion tai selityksen mitä tarkoittaa koodina? Olen tosiaan ohjelmoinnin perusteita aloittelemassa niin ei mene kovin helpolla kaaliin.
 
Liittynyt
20.10.2016
Viestejä
1 369
Saako tästä vielä sellaisen rautalankaversion tai selityksen mitä tarkoittaa koodina? Olen tosiaan ohjelmoinnin perusteita aloittelemassa niin ei mene kovin helpolla kaaliin.
Jos siis oot tuon ekan osan tehnyt jo niin apumuuttujaa apuna käyttäen vertailet uuden kierroksen arvoa edelliseen


Jotain tyyliin

while true
Syote = input("jätä viesti")
If syote == loppu TAI syote == edellinenViesti
Poistutaan toistolauseesta, muuten talletetaan syote edellinenViesti muuttujaan ja verrataan siihen ensi kierroksella syötettä
 
Liittynyt
21.11.2016
Viestejä
324
Pieni PHP kysymys, joka voi olla varsin simppeli, mutta ei nyt itselle aukea..

Koodi:
class A {
    private $test;

    public function __construct($name) {
        $this->test = $name;
    }

    public function getName() {
        return $this->test;
    }
}

class B extends A {
    
    public function showName() {
        $this->getName();
    }
}

$a = new A('testaaja');
$b = new B();

$a->getName();        // tulostaa testaaja
$b->showName();        // NULL
Mitä pitää nyt muuttaa niin, että tuo viimeinen rivi $b->showName osaisi kanssa tulostaa luokan A muuttujan sisällön?
 
Liittynyt
17.10.2016
Viestejä
5 658
Pieni PHP kysymys, joka voi olla varsin simppeli, mutta ei nyt itselle aukea..

Koodi:
class A {
    private $test;

    public function __construct($name) {
        $this->test = $name;
    }

    public function getName() {
        return $this->test;
    }
}

class B extends A {
   
    public function showName() {
        $this->getName();
    }
}

$a = new A('testaaja');
$b = new B();

$a->getName();        // tulostaa testaaja
$b->showName();        // NULL
Mitä pitää nyt muuttaa niin, että tuo viimeinen rivi $b->showName osaisi kanssa tulostaa luokan A muuttujan sisällön?
En nyt oo mikään PHP-guru, mutta minusta näyttää siltä että sulla menee luokat ja luokkien instanssit sekaisin. Eli sä luot tuolla muuttujan b jolla ei ole mitään tekemistä tuon muuttujan a kanssa. Se b on luokan B uusi (ja tyhjä) instanssi.

Mitä tarkalleen yrität tehdä noilla luokillasi?
 
Liittynyt
21.11.2016
Viestejä
324
En nyt oo mikään PHP-guru, mutta minusta näyttää siltä että sulla menee luokat ja luokkien instanssit sekaisin. Eli sä luot tuolla muuttujan b jolla ei ole mitään tekemistä tuon muuttujan a kanssa. Se b on luokan B uusi (ja tyhjä) instanssi.

Mitä tarkalleen yrität tehdä noilla luokillasi?
Jotenkin pelkäsinkin, että yksinkertaistettu ongelmani ei aukene sellaisenaan, joten uusi yritys:
Koodi:
class A {
    private $settings;

    public function __construct($settings) {
        $this->settings = $settings;
    }

    public function sendMail() {
        // mailin lähetys käyttäen $this->settings muuttujan asetuksia
    }
}

class B extends A {
    
    public function teeJotain() {
        $this->sendMail();
    }
}

$a = new A($settings);
$b = new B();

$a->sendMail();  // toimii
$b->teeJotain(); // ei toimi, koska settings muuttuja on null..
Eli luokassa A on methodeja, joista yksi on mailin lähetys. Luokkaa luodessa tallennetaan settings muuttujaan mailia asetukset. Nyt sit luokassa b on muita methodeja ja yhden niistä pitäisi lähettää myös mailia.

Mutta mailin lähetys ei toimi jos asetukset on muuttujassa. B luokasta voin kutsua onnistuneesti luokan A mailin lähetystä ja se toimii jos asetukset ovat kovakoodattuja tuolla sendMail methodissa..

Haluaisin siis kutienkin, että ne eivät ole kovakoodattuja.
 
Liittynyt
17.10.2016
Viestejä
5 658
Jotenkin pelkäsinkin, että yksinkertaistettu ongelmani ei aukene sellaisenaan, joten uusi yritys:
Koodi:
class A {
    private $settings;

    public function __construct($settings) {
        $this->settings = $settings;
    }

    public function sendMail() {
        // mailin lähetys käyttäen $this->settings muuttujan asetuksia
    }
}

class B extends A {
 
    public function teeJotain() {
        $this->sendMail();
    }
}

$a = new A($settings);
$b = new B();

$a->sendMail();  // toimii
$b->teeJotain(); // ei toimi, koska settings muuttuja on null..
Eli luokassa A on methodeja, joista yksi on mailin lähetys. Luokkaa luodessa tallennetaan settings muuttujaan mailia asetukset. Nyt sit luokassa b on muita methodeja ja yhden niistä pitäisi lähettää myös mailia.

Mutta mailin lähetys ei toimi jos asetukset on muuttujassa. B luokasta voin kutsua onnistuneesti luokan A mailin lähetystä ja se toimii jos asetukset ovat kovakoodattuja tuolla sendMail methodissa..

Haluaisin siis kutienkin, että ne eivät ole kovakoodattuja.
Niin siis tämä rivi:
$b = new B();

Se luo muuttujan b, joka on luokan B instanssi, minkä konstruktoriin et syötä mitään arvoa. Eli se muuttujan b sisäinen settings-muuttuja on tyhjä. Eikä se tiedä mitään muuttujasta a. Se luokka B vain perii ne luokan A metodit, muuttujat ei instanssien välillä mitenkään maagisesti kopioidu.

Riippuu aika paljon koko kokonaisuudesta että miten tuo nyt sitten kannattaisi järjestellä uusiksi.

Onko tuon teeJotain metodin pakko olla eriytettynä omaan luokkaansa? Helpoimmalla selvinnet jos vaan siirrät sen luokan A metodiksi. Voi tietty olla että jostain muusta syystä tämä ei ole toivottu ratkaisu.
 
Liittynyt
17.10.2016
Viestejä
4 589
Eli luokassa A on methodeja, joista yksi on mailin lähetys. Luokkaa luodessa tallennetaan settings muuttujaan mailia asetukset. Nyt sit luokassa b on muita methodeja ja yhden niistä pitäisi lähettää myös mailia.

Mutta mailin lähetys ei toimi jos asetukset on muuttujassa. B luokasta voin kutsua onnistuneesti luokan A mailin lähetystä ja se toimii jos asetukset ovat kovakoodattuja tuolla sendMail methodissa..

Haluaisin siis kutienkin, että ne eivät ole kovakoodattuja.
Ongelma on, että luot instanssin luokasta B, jolle et anna niitä asetuksia. Siksi ne on null.

Jos B ei tarvitse A:sta mitään muuta kuin mailin lähetyksen, niin miksi sen pitää periä luokka A? Voisiko se vain käyttää jotain A:n instanssia?
 
Liittynyt
25.10.2016
Viestejä
673
Kysytääs paljon viisaammilta kun C# do-while yms. toistolauseita räpellän että mikähän tässä mättää. Tämä on todella pelkistetty kokeilu, tarkoitus olisi vain käyttäjältä kysymällä saada looppi poikki.
Untitled.jpg
 
Liittynyt
20.10.2016
Viestejä
1 369
Kysytääs paljon viisaammilta kun C# do-while yms. toistolauseita räpellän että mikähän tässä mättää. Tämä on todella pelkistetty kokeilu, tarkoitus olisi vain käyttäjältä kysymällä saada looppi poikki.
Esittele tuo muuttuja ennen tuota do-whileä, silloin tuo ainakin toimii. :hmm: Ja niin tuo error taitaa sanoakin.
 
Liittynyt
25.10.2016
Viestejä
673
Esittele tuo muuttuja ennen tuota do-whileä, silloin tuo ainakin toimii. :hmm: Ja niin tuo error taitaa sanoakin.
Pystytkö näyttään vaikka kuvalla, yritän esitellä muutujan, mutta tulee " A local or parameter named 'luku2' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter" virheilmoitus.
 
Liittynyt
17.01.2018
Viestejä
1 997
Pystytkö näyttään vaikka kuvalla, yritän esitellä muutujan, mutta tulee " A local or parameter named 'luku2' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter" virheilmoitus.
Koodi:
int luku2 = 0;
do {
    luku2 = Convert.ToInt32(Console.ReadLine());
} while (luku2 != 0);
Siis määritetään muuttuja ennen koko looppia ja vain asetetaan arvo loopissa.
 
Liittynyt
25.10.2016
Viestejä
673
Koodi:
int luku2 = 0;
do {
    luku2 = Convert.ToInt32(Console.ReadLine());
} while (luku2 != 0);
Siis määritetään muuttuja ennen koko looppia ja vain asetetaan arvo loopissa.
No niin kiitoksia nyt toimii :thumbsup: Yritin tosiaan vielä loopin sisällä määritellä uudestaan tuota samaa luku2 muuttujaa int tyypillä.
 
Liittynyt
17.10.2016
Viestejä
401
No niin kiitoksia nyt toimii :thumbsup: Yritin tosiaan vielä loopin sisällä määritellä uudestaan tuota samaa luku2 muuttujaa int tyypillä.
Kannattaa myös opetella lukemaan noita kääntäjän/linterin virheilmoituksia ajatuksen kanssa, tuossa ylläolevassa virheilmossa se kerrottiin melko tarkasti, miksi se ei toimi. Tarkoitus siis ei ole vittuilla, itse olin myös aikoinaan laiska noita lukemaan kun opettelin koodaamista ja googlettelin kaiken.
 
Liittynyt
17.01.2018
Viestejä
1 997
No niin kiitoksia nyt toimii :thumbsup: Yritin tosiaan vielä loopin sisällä määritellä uudestaan tuota samaa luku2 muuttujaa int tyypillä.
Alkuperäisessä oli loopin ulkopuolella luku1 ja loopissa luku2.
Eli ehkä se luku1 olikin kirjoitusvirhe vaikka piti esitellä luku2 ?

Mutta kuten @Technocrat jo kertoi kannattaa opetella lukemaan virheitä, muuten ei pääse kovin pitkälle...
 
Liittynyt
28.08.2018
Viestejä
772
Ymmärrän nyt miten tämä toimii, mutta en ymmärrä vielä miten käytän sitä oikein
if __name__ == "__main__":
main()

elikkäs laitetaanko kaikki koodi myös muuttujat ja muut funktiot kaikki tuohon def main(): alle? vai tulisko muuttujat, muutujien alustus, ja muut def funktiot olla ulkopuolella?
def main():

rupesin nyt olemassa olevaan python koodiini lisäämään tätä if toimintoa, mutta rupesin siirtämään kaiken sen alle ja aikamoinen työ vetää joka riville yks tab "4space". Olisiko vain se koodi missä käytetään def funktioita siirrettävä main:in alle?

edit: siirsin nyt kaiken def mainin alle ja koodi ainakin toimii. en tiedä olisiko siinä mitään pahaa jos muuttujat ja def funkkarit olisivat ulkopuolella. ymmärränkö oiken että jos funktiot olisivat ulkopuolella, niitä voisi käyttää ulkopuolelta? nyt kun kaikki on mainin alla niin vain tämä kirjasto saa luvan käyttää funktioita ja koko koodia.
 
Viimeksi muokattu:
Liittynyt
17.10.2016
Viestejä
14 550
aikamoinen työ vetää joka riville yks tab "4space"
Hommaa kunnon editori (Visual Studio Code), maalaa hiirellä tai sopivalla näppäinkomennolla haluamasi rivit ja paina kerran tabia. (Ja säädä se editori tajuamaan oikea määrä sisennystä oikealla tavalla.) Ei tarvitse sisentää joka riviä erikseen välilyöntiä hakkaamalla :D

Yleisesti ottan: jos muuttujaa tarvitaan vain jossain tietyssä funktiossa, määrittele se siellä funktiossa. Näin ulkomaailman ei tarvitse välittää tai tietää tuon muuttujan olemassaolosta tuon taivaallista ja homma selkiytyy. Sama koskee lähtökohtaisesti myös funktioita. Pienet apufunktiot, joita käytetään vain yksittäisen funktion sisällä, voi myös määritellä siellä. Näin ulompi namespace pysyy "puhtaana". On sitten vähän tilanteesta kiinni, milloin tuollainen sisäkkäisyys on selkeää ja milloin se hankaloittaa koodin lukemista.

Joskus sellainen on pakollinen, kun haluat palauttaa funktiosta uuden funktion, joka käyttää ulomman funktion parametria tässä sisemmässä funkkarissa. Googlaa "python closure", jos kiinnostaa nähdä.
 
Toggle Sidebar

Statistiikka

Viestiketjut
237 362
Viestejä
4 158 459
Jäsenet
70 411
Uusin jäsen
allun90

Hinta.fi

Ylös Bottom