- Estetty
- #1 301
- Liittynyt
- 17.10.2016
- Viestejä
- 2 307
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.Onko tällaisista intensiivikursseista mitään apua jos lähtee ns. nollista liikkeelle esim. alan vaihtoa suunnittelevalle?
Etusivu
Koodaamista voisi verrata vaikkapa säveltämiseen. Toisilta se käy luonnostaan ja toiset oppivat opiskelemalla. Yhtä kaikki, koodia syntyy. AMKoodari on koulutus sinulle, joka haluat oppia tulevaisuuden ammatin, päivittää osaamistasi, vaihtaa uraa tai muutamkoodari.fi
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.Onko tällaisista intensiivikursseista mitään apua jos lähtee ns. nollista liikkeelle esim. alan vaihtoa suunnittelevalle?
Etusivu
Koodaamista voisi verrata vaikkapa säveltämiseen. Toisilta se käy luonnostaan ja toiset oppivat opiskelemalla. Yhtä kaikki, koodia syntyy. AMKoodari on koulutus sinulle, joka haluat oppia tulevaisuuden ammatin, päivittää osaamistasi, vaihtaa uraa tai muutamkoodari.fi
Mainospuheet ainakin ovat hienot mutta miten todellisuus?
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())
}, [])
}
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.Jos on, niin mielelläni luen vinkkejä siitä miten tuo tehdään paremmin.
Aika simppelillä kaavalla tuosta selviää: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?
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.Aika simppelillä kaavalla tuosta selviää:
=DATE(LEFT(A1,4), MID(A1,5,2), RIGHT(A1,2))
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.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.
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?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?
Tietokantaa ei tarvitsisi tuossa olla, mutta jonkinlainen yhteys tiedostoihin.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.
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.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..
var io = require('socket.io')(server);
const nsp = io.of('/rakennusc/1/keittiö');
nsp.on('connection', function(socket){
console.log('Client connected ');
exports.server = server
const www = require("../bin/www");
var io = require('socket.io')(www.server);
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?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ä?
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
@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%
@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%
En tiedä saitko jo toimimaan, mutta tarkoitin siis jotain tällaista: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?
// 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);
//...
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);
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"]);
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.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.
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
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.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.
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):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.
function test_FastReader():
DownloaderObjectFactory.nextInstanceType = "mock";
FR = FastReader();
# testausta
DownloaderObjectFactory.nextInstanceType = "normal";
Piti jo aiemmin laittaa kiitosta tästä, mutta en näemmä ollut laittanut. Eli kiitos. Tämä toimii hienosti.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%
Riippuu siitä mikä kyselee ja miten. Jos sen joutuu kirjoittamaan terminaaliin niin voi olla että joutuu tekemään tyyliinPiti 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?
Saako tästä vielä sellaisen rautalankaversion tai selityksen mitä tarkoittaa koodina? Olen tosiaan ohjelmoinnin perusteita aloittelemassa niin ei mene kovin helpolla kaaliin.if input sama kuin loppu tai sama kuin edellinensana varmaan toiminee
Jos siis oot tuon ekan osan tehnyt jo niin apumuuttujaa apuna käyttäen vertailet uuden kierroksen arvoa edelliseenSaako tästä vielä sellaisen rautalankaversion tai selityksen mitä tarkoittaa koodina? Olen tosiaan ohjelmoinnin perusteita aloittelemassa niin ei mene kovin helpolla kaaliin.
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
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.Pieni PHP kysymys, joka voi olla varsin simppeli, mutta ei nyt itselle aukea..
Mitä pitää nyt muuttaa niin, että tuo viimeinen rivi $b->showName osaisi kanssa tulostaa luokan A muuttujan sisällön?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
Jotenkin pelkäsinkin, että yksinkertaistettu ongelmani ei aukene sellaisenaan, joten uusi yritys: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?
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..
Niin siis tämä rivi:Jotenkin pelkäsinkin, että yksinkertaistettu ongelmani ei aukene sellaisenaan, joten uusi yritys:
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.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..
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.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.
Esittele tuo muuttuja ennen tuota do-whileä, silloin tuo ainakin toimii. Ja niin tuo error taitaa sanoakin.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.
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.Esittele tuo muuttuja ennen tuota do-whileä, silloin tuo ainakin toimii. 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.
int luku2 = 0;
do {
luku2 = Convert.ToInt32(Console.ReadLine());
} while (luku2 != 0);
No niin kiitoksia nyt toimii Yritin tosiaan vielä loopin sisällä määritellä uudestaan tuota samaa luku2 muuttujaa int tyypillä.Siis määritetään muuttuja ennen koko looppia ja vain asetetaan arvo loopissa.Koodi:int luku2 = 0; do { luku2 = Convert.ToInt32(Console.ReadLine()); } while (luku2 != 0);
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.No niin kiitoksia nyt toimii Yritin tosiaan vielä loopin sisällä määritellä uudestaan tuota samaa luku2 muuttujaa int tyypillä.
Alkuperäisessä oli loopin ulkopuolella luku1 ja loopissa luku2.No niin kiitoksia nyt toimii Yritin tosiaan vielä loopin sisällä määritellä uudestaan tuota samaa luku2 muuttujaa int tyypillä.
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ä hakkaamallaaikamoinen työ vetää joka riville yks tab "4space"