Tie Koodariksi sivusto ja apua tehtävissä

Liittynyt
18.10.2016
Viestejä
49
Terve,

En löytänyt ko. sivustoon (tie.koodariksi.fi) liittyvää threadia, mutta pahoittelut jos sellainen jo on.
Vaikka sivusto on ilmeisesti tarkoitettu nuoremmille, niin kivahan noita on harjoitella myös näin vanhemmalla iällä.
Törmäsin kuitenkin nyt ylitsepääsemättömään ongelmaan ja täältä varmastikin löytyy apua/osaajia:

Ohjelmoinnin alkeet, luku 6 ja tehtävä 6:
Tässä on paksu portaikko, jossa on 3 askelmaa:
###
# #
#####
# # #
#######
# # # #
#######

Tee ohjelma, joka tulostaa silmukan avulla vastaavan portaikon, jossa on 30 askelmaa.

Onko joku saanut tuon tehtävän ratkaistua onnistuneesti? Mielestäni tuo tehtävänanto ei ole selkeä, koska tuo viimeinen rivi on yhtä pitkä kuin edellisellä askelmalla? Yritin tehdä pari versiota missä "####"-rivi on yhtä pitkä kuin "# # #"-rivi, mutta eivät kelvanneet :(
Esimerkiksi näin:
"

apu = 2
for i in range(3,61,2):
print("#"*i)
print("# "*apu)
apu += 1
"
 
Se viimeinen rivi on poikkeus ja kuvaa alimman askelman "alapuolta". Muutoin kannattaa tehdä ensin funktio, joka printtaavain yhden askelman eli kaksi riviä merkkejä. Se ottaa vaikka parametriksi luvun 5 ja printtaa:

Koodi:
#####
# # #

(Protip: käytin CODE-tagejä niin nuo merkit tai koodit tulostuvat täällä foorumilla oikein).

Miten se tapahtuu? No sulla on jo oikein tuo print("#" * size). Se toinen rivi olisi sopiva määrä noita "# "-merkkijonoja peräkkäin ja loppuun vielä yksi ylimääräinen #. Laske aluksi käsin, mikä olisi oikea määrä eri askelmakoilla niin varmaan keksit sen yksinkertaisen laskun jolla oikea määrä löytyy. Eli kun askelkoko on 3, tarvitaan 1 toisto, askelkoolla 5 tarvitaan 2, askelkoolla 7 tarvitaan 3. 9 -> 4. 11 -> 5. Keksitkö kaavan tuolle?

Koodi:
###
# #
#####
# # #
#######
# # # #


Kun tuo funkkari toimii hyvin parametreillä 3, 5, 7, 9 jne. Voit tehdä sen loopin joka sitten käyttää tuota funktiota. Se sulla sunnilleen onkin. Loppuun pitää vielä printata se alin rivi, joka on viimeisen askelman leveys. Taas kerran, tee tästä funktio, joka ottaa parametriksi askelmien lukumäärän. Esim. arvolla 1 se printtaa vain yhden 3:n levyisen askelman ja sen alarivin. Arvolla 2 se printtaa kaksi askelmaa: 3 ja 5-levyiset jne. Näin opit tekemään ns. geneerisiä funktioita, joita on helppo käyttää eri tilanteissa vain muokkaamalla annettua parametria.
 
Hah, kiitos!
jännä miten ihmisten aivot toimii eri tavalla. Ymmärsin selityksesi erittäin hyvin, mutta kun yritin vääntää sitä koodiksi, niin
sain aikaiseksi vain tämän pätkän, joka siis kelpasi ratkaisuksi:
Koodi:
apu = 2
for i in range(3,62,2):
    print("#"*i)
    print("# "*apu)
    apu += 1
print("#"*i)

Jatkan harjoituksia :)
 
Joo, saman tuloksen saa eri tavoilla. Toi sun printtaa sinne sen "turhan" välilyönnin sen viimeisen #:n jälkeen. Mutta se ei varmaan haittaa tässä tehtävässä. Hyvä että toimii!
 
Ja taas ollaan jumissa :)
Luku 7, tehtävä 6:
"
Tarkastellaan lukujonoa, jossa on ensin kerran luku 1, sitten kahdesti luku 2, sitten kolmesti luku 3, jne. Lukujono alkaa siis 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, ...
Tee ohjelma, joka tulostaa lukujonon 100 ensimmäistä lukua, jokainen luku omalle rivilleen.
"

Ilmeisesti siis on tarkoitus tulostaa 100 riviä numeroita, eli lyhyellä matematiikalla tuo tulee täyteen kun luku 14 on tulostettu kuusi kertaa.

Koodilla:
Koodi:
for i in range (1,X):
    for a in range(i):       
        print(i)

Saan jo nuo lukujen määrät toimimaan, mutta tuota X-numeroa vaihtelemalla pystyn vaikuttamaan vain numeroiden määrään, enkä siihen että suoritus pysähtyisi 100. rivin jälkeen. Ilmeisesti tässä ei nyt vielä ole mitään "while"-tyyppisiä käskyjä käytössä, vaan pitäisi pärjätä tuolla for-silmukalla. Mitä en nyt huomaa?
 
Siinä voi tehdä vaikka muuttujan jonka arvo on 100 ja jota pienennetään joka tulostuksella yhdellä. Tulostus lopetetaan kun muuttuja on nollassa.
 
Siinä voi tehdä vaikka muuttujan jonka arvo on 100 ja jota pienennetään joka tulostuksella yhdellä. Tulostus lopetetaan kun muuttuja on nollassa.

Tätä olen tässä sadepäivän ratoksi pähkäillyt. Miten lopetan tulostuksen kun muuttuja on nollassa?
Taidot eivät riitä siihen käyttäen tuota for-silmukkaa :(
 
Tätä olen tässä sadepäivän ratoksi pähkäillyt. Miten lopetan tulostuksen kun muuttuja on nollassa?
Taidot eivät riitä siihen käyttäen tuota for-silmukkaa :(
If:llä vaan katsot saako tulostaa:

Koodi:
x = 100
for i in range (1,15):
    for a in range (i):
        if (x > 0):
            print(i)
        x -= 1
 
Ihan mielenkiintoisia tehtäviä tuolla. Muistuttaa hieman ohjelmointiputkan PHP haastetta
 
Kiitos @njs ! Nyt lähti homma rokkaamaan. Vaikka itse olen vahvasti HW-puolen ihmisiä, niin olen ymmärtänyt että "oikeissa" koodausohjelmissa on apuna kaikenlaisia debuggereita tms. joilla näkee paremmin, että mitä ohjelmassa tapahtuu ja mitä ei.
Näillä nettikursseilla mennään vähän sokkona, kun on ensin muutama helppo esimerkki ja sitten hypätäänkin jo syvään päähän tehtävien kanssa. Mutta mutta, kivaahan tämä on ja kiva, että apuja löytyy kun omat taidot loppuvat.
 
Nyt on pakko taas kysyä viisaammilta apuja jottei koko joulu mene plörinäksi.
Ehkä pulma liittyy enemmän shakkiin tai matematiikkaan, kuin koodin vääntämiseen, mutta pulassa ollaan joka tapauksessa tämän kanssa:
"
On 16 tapaa sijoittaa musta ja valkea kuningatar 3x3-shakkilaudalle niin, että ne eivät uhkaa toisiaan. Mikä on tapojen määrä 8x8-shakkilaudalla?
"

Tiedän, että musta voidaan sijoittaa tuolle 3x3 laudalle yhdeksällä ja valkoinen kahdeksalla tavalla, eli 9x8=72 mahdollista kombinaatiota, joista 16 on turvallista. Ja koska kuningatar pystyy liikkumaan laudan koosta riippumatta, niin samat positiot ovat uhkaavia kuin pienemmässäkin versiossa + ne kaikki isommat ulkoreunat.

Koodia (varmaankin if lauseketta) en tästä saa vain mitenkään aikaiseksi :(
 
Nyt on pakko taas kysyä viisaammilta apuja jottei koko joulu mene plörinäksi.
Ehkä pulma liittyy enemmän shakkiin tai matematiikkaan, kuin koodin vääntämiseen, mutta pulassa ollaan joka tapauksessa tämän kanssa:
Innostuin itsekin näitä tekemään ja juurikin samassa kohtaa. Enemmän tosiaan matematiikkaa kuin koodausta, mutta vielä ei onnistunut ratkaisu :)
 
Pari ajatusta:
  • Käy läpi kaikki mahdolliset positiot
  • Joka positiossa tsekkaa, uhkaavatko nappulat toisiaan
  • nappulat uhkaavat toisiaan, jos ovat samalla:
    • rivillä - x-koordinaatti sama
    • linjalla - y-koordinaatti sama
    • diagonaalilla - x-koordinaattien ero == y-koordinaattien ero
  • Nopeutta lisää ottamalla laudan symmetriat huomioon, mutta tuskin tarvitsee tässä tehtävässä
 
muoks. oli kyllä niin sontaa koko oma postaus, kun luin tota tehtävää hätäisesti, että siivotaan sotkemasta muiden miettimistä :D
 
Viimeksi muokattu:
Pari ajatusta:
  • Käy läpi kaikki mahdolliset positiot
  • Joka positiossa tsekkaa, uhkaavatko nappulat toisiaan
  • nappulat uhkaavat toisiaan, jos ovat samalla:
    • rivillä - x-koordinaatti sama
    • linjalla - y-koordinaatti sama
    • diagonaalilla - x-koordinaattien ero == y-koordinaattien ero
  • Nopeutta lisää ottamalla laudan symmetriat huomioon, mutta tuskin tarvitsee tässä tehtävässä

Juuri tuo diagonaali testaus oli hukassa, tosin ei ihan onnistunut:

Koodi:
u = 0
v = 0
x = 4
for a in range(1,x):
    for b in range(1,x):
        for c in range(1,x):
            for d in range(1,x):
                if a == c or b == d or (a-c == b-d):
                    u += 1
                else:
                    v += 1
Tuolla tulee v:n arvoksi 26, kun pitäisi olla 16.
 
Oiskohan tuossa @njs n koodissa nyt se vika, että se antaa mahdollisuuden nappuloille olla samassa ruudussa, eli kun musta on jo sijoitettu laudalle, niin valkoiselle on yksi ruutu vähemmän käytössä.
En kyllä osaa poistaa tuosta noita dublikaatteja, mutta jatketaan mietintöjä.
 
Duplojen poistoon vaikka lista jossa pitää kirjaa käytetyistä xy yhdistelmistä. Itse sain tuossa shakkitehtävässä 3x3 ruudun oikein, mutta muut kusee. Jostain pienestä varmasti kiinni
 
  • diagonaalilla - x-koordinaattien ero == y-koordinaattien ero
Tätä kun hetken pohti niin totesin, että pitää vertailla itseisarvoja, nyt toimii:

Koodi:
v = 0
x = 9
for valX in range(1,x):
    for valY in range(1,x):
        for musX in range(1,x):
            for musY in range(1,x):
                if (valX != musX and valY != musY):
                    if abs(valX - musX) != abs(valY - musY):
                        v += 1
print(v)
Edit: korjattu muuttujat
 
Viimeksi muokattu:
Juuri tuo diagonaali testaus oli hukassa, tosin ei ihan onnistunut:

Protip #123, älä helvetissä anna tollasia muutujanimiä ikinä :D a, b, c, d, u, v, x Menee turhaa aikaa kun miettii, mitä nuo yrittävät esittää. Mutta tosiaan, ensinnäkin sulla on tuo diagonaalin tarkastus väärin. Onko 2-3 == 2-1. Ei ole, mutta silti ne oikeasti uhkaavat toisiaan. Eli tuon kun fiksaat, niin toiminee. Sillä tuskin on tässä väliä, että annat nappuloiden olla samassa ruudussa. Se ei vaikuta kuitenkaan tuohon sallittujen positioiden lukumäärään, sillä testi katsoo, että samassa ruudussa olevat uhkaavat toisiaan.

Ja noi kaikki mahdolliset positiot voi generoida niin, ettet laita nappuloita samaan ruutuun. Esim. näin 2x2-laudalla. A on toinen nappula, B toinen ja piste on tyhjä ruutu.

Koodi:
..  B.  .B  B.  .B  AB
AB  A.  A.  .A  .A  ..

Eli 6 eri asemaa (ilman symmetrioita). Tuossa B aloittaa aina A:n vierestä ja luuppaa oikealle ja ylös kunnes päätyy viimeiseen ruutuun oikeassa yläkulmassa. Sitten A siirtyy yhden eteenpäin ja sama toistuu. Tämänkin voi tehdä monella tavalla.

EDIT: näköjään sait tuon diagonaalin fiksattua.
 
Selkeästi näissä tehtävissä tarvitaan jo yliopistotason matematiikkaosaamista ja "ohjelmoinnin alkeet" kuulostaa kovin vähättelevältä. Kiitos kuitenkin kaikille, sain tehtävän suoritettua ja ymmärsinkin, että mitä tein.
Otetaas seuraavaksi paljon helpompi ongelma:
"
Luvuissa 1,2,...,10 on yhteensä 11 numeroa. Montako numeroa on yhteensä luvuissa 1,2,...,1000?"
"

mikäs olikaan se käsky millä pystyi tulostamaan numeroita yhteen pötköön? Saan helposti tulostettua numerot 1,2,3... allekkain, mutta tarvitsisin ne peräkkäin, jotta saisin muutettua numeron merkkijonoksi ja sitä kautta laskettua jonon pituuden?
 
Jos tuollai teet, niin ei kai sun tarvii tulostaa mitään ennen valmista, vaan luupata yhdestä tuhanteen ja putkittaa jokainen indeksin luku merkkijonona muuttujaan. Lopuksi sulla on merkkijonomuuttuja, jonka pituus on tuon vastaus. Tuolla tavalla tulee vaan tarpeettomia tyyppimuunnoksia, joista en edes muista kunnolla, miten ne Pythonissa käyttäytyvät, kun Pythonia tarvii käyttää niin pirun harvoin :D

Ite tekisin näin pikaisella miettimisellä mieluummin jotenkin seuraavasti, eli jos luuppaa indeksit yhdestä tuhanteen, niin

- kaikissa luvuissa alle 10 on 1 numero,
- kaikissa luvuissa yli 10, mutta alle 100 on 2 numeroa,
- kaikissa luvuissa yli 100, mutta alle 1000 on 3 numeroa ja
- luvussa 1000 on 4 numeroa.

Ja noiden ehtojen perusteella kasvattaa laskuria luupin sisällä.

P.S toivottavasti luin tän tehtävän nyt riittävän oikein :D
 
Viimeksi muokattu:
Selkeästi näissä tehtävissä tarvitaan jo yliopistotason matematiikkaosaamista ja "ohjelmoinnin alkeet" kuulostaa kovin vähättelevältä. Kiitos kuitenkin kaikille, sain tehtävän suoritettua ja ymmärsinkin, että mitä tein.

No ei nyt sentään. Mutta enemmänkin sellaista loogista ajattelutapaa ja kykyä pilkkoa se ongelma järkeviksi pikkuongelmiksi, jotka sitten voi koodata ohjelmaan. Kokemuksen kautta sen oppii, ei niinkään yliopiston matematiikankursseilla.

Otetaas seuraavaksi paljon helpompi ongelma:
"
Luvuissa 1,2,...,10 on yhteensä 11 numeroa. Montako numeroa on yhteensä luvuissa 1,2,...,1000?"
"

mikäs olikaan se käsky millä pystyi tulostamaan numeroita yhteen pötköön? Saan helposti tulostettua numerot 1,2,3... allekkain, mutta tarvitsisin ne peräkkäin, jotta saisin muutettua numeron merkkijonoksi ja sitä kautta laskettua jonon pituuden?

Numerot saa pötköön vaikkapa muuttamalla ne ensin merkkijonoksi str() komennolla ja sitten +-operaattorilla voi yhdistää merkkijonoja toisiinsa. Tai siten voit käyttää vain len() funkkaria ja katsoa merkkijonon pituuden ja ynnäillä ne yksittäin, jolloin ei tarvitse "valtavaa" merkkijonoa pitää muistissa.

Tai sitten vois auttaa lukiomatematiikka, jos haluaa kirjoittaa funktion, joka ottaa kokonaisluvun parametriksi ja antaa tulokseksi luvun numeroiden määrän. 10-kantainen logaritmi kertoo sen. Jos katsoo, mitä log 9, log 10, log 99, log 100, log 999 ja log 1000 antavat tulokseksi, niin saa tuon ongelman myös ratkottua.

Monta tapaa tossakin tehdä.
 
Tuo logaritmin käyttäminen lienee se elegantein ratkaisu. Eipä tullut äsken mieleen.

muoks. tai no, pitäähän tässäkin käsitellä vielä tuota logaritmin palauttamaa vastausta, eli pyöristää seuraavaan kokonaislukuun. Kirjoitin äsken taas ihan omiani, jos joku kerkes lukemaan ennen muokkausta.

lisämuoks. otan takas, ehkä tuo puupää iffailu on sittenkin omaan makuun intuitiivisempaa :D Nythän esim. log(14) = n. 1,146 ja tuollaiset pitää pyöristää sit omalla ehdollaan seuraavaan kokonaislukuun, eikä voi luottaa koko aikaa edes automaattisiin pyöristyssääntöihin.
 
Viimeksi muokattu:
Eleganttiudesta nyt tiedä, mutta itselleni järkeenkäyvin ratkaisu näyttää tältä:
Koodi:
summa = 0
for i in range(1,1001):
    s = str(i)
    summa += len(s)
print(summa)

ja näin jälkikäteen katseltuna se näyttää helpolta ja ymmärrettävältä, mutta enpä olisi saanut sitä aikaiseksi ilman palstalaisten hyviä vinkkejä.

edit. sain seuraavan itse ratkaistua.
 
Viimeksi muokattu:
Kirjoita ekaksi funktio joka tosiaan ottaa parametriksi yhden luvun ja laskee sen numeroiden summan. Olit täysin oikeilla jäljillä, miten sen tehdään. str() muuttaa luvun merkkijonoksi. Sitten sun pitäisi muuttaa jokainen merkki luvuksi. int() muuttaa yhden merkkijonon kokonaisluvuksi. Eli enää pitää keksiä, miten käydään ne merkit läpi? Siihen on monta tapaa:
  • Voit luupata jokaisen merkin for-luupilla. Luupin sisällä sitten muutat c:n kokonaisluvuksi ja ynnäät johonkin muuttujaan.
  • Voit tehdä ns. list comprehensionin tyyliin [int(c) for c in str(luku)]. Tuo on vain tiiviimpi muoto siitä for loopista. Kokeile! Tuon tuloksena syntyy uusi lista, jossa on ne yksittäiset numerot numeroina. Sitten tuon voi kääriä kätevästi sum-funktion sisään, joka laskee ne yhteen.
  • Voit käyttää reduce() funktiota, jolle annetaan lista ja funktio, joka sitten ottaa seuraavan alkion listasta, muuttaa kokonaisluvuksi ja summaa yhteen ja palauttaa lopputuloksen. Joskus näppärä tapa typistää lista asioita joksikin yhdeksi asiaksi.
 
Näköjään nuo sivujen viimeiset tehtävät ovat jo sitä luokkaa, että sormi on syvällä suussa, kuten esim. tämä:
"
Positiivinen kokonaisluku on onnenluku, jos sen jokainen numero on 4 tai 7. Ensimmäiset onnenluvut ovat 4, 7, 44, 47, 74 ja 77.
Tee ohjelma, joka tulostaa pienimmästä suurimpaan onnenluvut, jotka ovat pienempiä kuin 10000.
"

Nyt ei edes sytytä, että miten voisi lähteä aloittamaan.
 
Näköjään nuo sivujen viimeiset tehtävät ovat jo sitä luokkaa, että sormi on syvällä suussa, kuten esim. tämä:
"
Positiivinen kokonaisluku on onnenluku, jos sen jokainen numero on 4 tai 7. Ensimmäiset onnenluvut ovat 4, 7, 44, 47, 74 ja 77.
Tee ohjelma, joka tulostaa pienimmästä suurimpaan onnenluvut, jotka ovat pienempiä kuin 10000.
"

Nyt ei edes sytytä, että miten voisi lähteä aloittamaan.

Muutat luvun merkkijonoksi ( str() ) ja käyt jokaisen merkin läpi. Jos merkki on eri kuin 4 tai 7 palauta false ja siirry seuraavaan lukuun.

Avautuuko tosta enemmän?
 
Eleganttiudesta nyt tiedä, mutta itselleni järkeenkäyvin ratkaisu näyttää tältä:

...

ja näin jälkikäteen katseltuna se näyttää helpolta ja ymmärrettävältä, mutta enpä olisi saanut sitä aikaiseksi ilman palstalaisten hyviä vinkkejä.
Ensimmäisenä pitää todeta, että opetteluvaiheessa on jo tosi paljon, jos ymmärtää, miksi ja miten joku tuollainen vastaava koodi toimii. Eli seuraava on täysin ulkona tällaisten tehtävien skoopista.

Mutta sitten kun kirjoitellaan koodia muiden luettavaksi ja ylläpidettäväksi, niin mahdollisimman kompakti tai pikkunäppärä ratkaisu ei ole aina paras, jos seuraavalla samaan koodiin koskevalla menee kauan ymmärtää, mitä koodi tekee. Minusta tuo koodi ei varsinaisesti huuda sitä, että nyt lasketaan kaikkien numeroiden summaa luvuista yhdestä tuhanteen :)

Eli kommentoimaan kannattaisi ainakin opetella het alkuunsa. Kaikki sellainen logiikka, joka ei ole täysin ilmeistä, kannattaa kommentoida auki. Parilla kommenttirivillä ja muuttujien sopivalla nimeämisellä tuokin kyseinen ratkaisu olisi jokaiselle lukijalle sekunneissa täysin ilmeinen :)
 
Muutat luvun merkkijonoksi ( str() ) ja käyt jokaisen merkin läpi. Jos merkki on eri kuin 4 tai 7 palauta false ja siirry seuraavaan lukuun.

Avautuuko tosta enemmän?

Ehkä nyt pääsin jo vähän sinnepäin, mutta ei kuitenkaan. Tuota "return false" tms. komentoa en vielä keksinyt, kun sellaista ei ole vielä opetettu :D, mutta tällä testikoodilla räpelsin ja en nyt vielä kehtaako tuota avautumiseksi vielä sanoa:
Koodi:
for i in range(1,100):
    jono = str(i)
    for merkki in jono:
        if merkki != "4" and merkki != "7":
            print("apua")
        else:
            print(i)
 
Regexillä hoituu vähän paremmin...
Koodi:
import re

re.match(r"^[47]+$", str(i))
 
Tuota "return false" tms. komentoa en vielä keksinyt, kun sellaista ei ole vielä opetettu :D
Tuossa materiaalissako ei ole opetettu funktioita, jotka palauttaa jonkin arvon? Tuota return falsea varten sulla pitää olla funktio, joka palauttaa totuusarvon (joko true tai false). Funktiot voi palauttaa muutakin, tyyliin objektin, luvun, merkkijonon ja tietyissä kielissä toisen funktionkin. Sulla näyttäis kaikki funktiot olevan tuollaisia, jotka tulostaa jotain, niin seuraava askel olis ymmärtää tuo arvon palauttaminen funktiosta.

Tuota sun tekemää koodinpätkää varten voisi olla vaikka apufunktio, joka tekee em. tarkastuksen ja palauttaa true tai false:

Koodi:
def onnenluku(merkkijono):
    for merkki in merkkijono:
        if merkki != "4" and merkki != "7":
            return False
    return True

for i in range(1,100):
    jono = str(i)
    print(jono) if onnenluku(jono) else continue

Eli tosiaan tuolla apufunktiossa käydään parametrina saatu merkkijono läpi merkki merkiltä, kuten sun omassakin ratkaisussa ja jos jokin vastaantuleva merkki on jotain muuta kuin 4 tai 7, funktio palauttaa falsen.

Jos merkkijono on käyty läpi ja kaikki merkit ovat 4 tai 7, niin funktio palauttaa true.

Tämän apufunktion avulla "pääfunktiossa" tulostetaan luvut, joiden kohdalla apufunktio palauttaa true.

muoks. korjattu else lohko mukaan

Regexit on hirveän näppäriä, kunhan vaan on tarkasti perillä, mitä ne milloinkin tekee :D

muoks. laitan ton koodin spoileritägeihin.
 
Viimeksi muokattu:
@pappatech
tuossa materiaalissa käydään läpi funktiot vasta ihan viimeisessä luvussa.

Ylipäätään tuolla materiaalissa on minimimäärä sisältöä ja uskon, että tuo on tarkoitettu enemmän jollekin kurssille sellaiseksi, jota opettaja käyttää tehtävänantoina..
 
^ asia kunnossa, tattis selvennyksestä. Ois pitänyt vähän selata tuota matskua, mutta lomalla laiskottaa :)
 
Tuossa materiaalissako ei ole opetettu funktioita, jotka palauttaa jonkin arvon? Tuota return falsea varten sulla pitää olla funktio, joka palauttaa totuusarvon (joko true tai false). Funktiot voi palauttaa muutakin, tyyliin objektin, luvun, merkkijonon ja tietyissä kielissä toisen funktionkin. Sulla näyttäis kaikki funktiot olevan tuollaisia, jotka tulostaa jotain, niin seuraava askel olis ymmärtää tuo arvon palauttaminen funktiosta.

Tuota sun tekemää koodinpätkää varten voisi olla vaikka apufunktio, joka tekee em. tarkastuksen ja palauttaa true tai false:

Koodi:
def onnenluku(merkkijono):
    for merkki in merkkijono:
        if merkki != "4" and merkki != "7":
            return false
    return true

for i in range(1,100):
    jono = str(i)
    print(jono) if onnenluku(jono)

Eli tosiaan tuolla apufunktiossa käydään parametrina saatu merkkijono läpi merkki merkiltä, kuten sun omassakin ratkaisussa ja jos jokin vastaantuleva merkki on jotain muuta kuin 4 tai 7, funktio palauttaa falsen.

Jos merkkijono on käyty läpi ja kaikki merkit ovat 4 tai 7, niin funktio palauttaa true.

Tämän apufunktion avulla "pääfunktiossa" tulostetaan luvut, joiden kohdalla apufunktio palauttaa true.

Regexit on hirveän näppäriä, kunhan vaan on tarkasti perillä, mitä ne milloinkin tekee :D

muoks. laitan ton koodin spoileritägeihin.

Kuten negge jo toteaakin, niin ihan hirvittää miten vähän kappaleiden alussa on selitetty/opetettu asioita ja sitten pitäisi hypätä suoraan syvään päähän. Esimerkiksi en saanut tuota funktiomallista koodia toimimaan ollenkaan.
Ehkä tämä kurssi ei tosiaan ole sellainen, jota voisi itseopiskelemalla edetä pelkästään sivuston kautta, vaan pitäisi hankkia tietoa ympäri internettiä (ja sitähän löytyy). Ihmetykset jatkuvat...
 
Kuten negge jo toteaakin, niin ihan hirvittää miten vähän kappaleiden alussa on selitetty/opetettu asioita ja sitten pitäisi hypätä suoraan syvään päähän. Esimerkiksi en saanut tuota funktiomallista koodia toimimaan ollenkaan.
Ehkä tämä kurssi ei tosiaan ole sellainen, jota voisi itseopiskelemalla edetä pelkästään sivuston kautta, vaan pitäisi hankkia tietoa ympäri internettiä (ja sitähän löytyy). Ihmetykset jatkuvat...
Heh, äsken korjasin typon siitä printtaus-lausekkeesta. Noissa pythonin inline iffeissä pitää näköjään olla pakosta else-lohkokin. Tulee tosiaan pirun vähän käytettyä Pythonia mihinkään. Kokeiles vielä, kai tuon pitäs logiikaltaan olla ihan kondiksessa. Ei oo myöskään tällä henkkoht koneella pythonia, enkä jaksanut foorumia varten asentaa, niin en tullut ajaneeksi ite tota (sorit siitä :D ).

Moocin ohjelmoinnin perusteet Javalla on materiaalina minusta tosi hyvä, mutta hyviä Python-matskuja en osaa vinkata.

muoks. ja voi ristus sentään, pythonissahan True ja False kirjoitetaan isolla. Korjasin senkin. Ehken kirjoittele enää pythonia ajamatta koodia :D
 
Viimeksi muokattu:
Näin onnistuu myös:
Koodi:
nums = set()
for i in range(16):
    num1 = f'{i:b}'.replace('0', '4').replace('1', '7')
    num2 = f'{i:b}'.replace('0', '7').replace('1', '4')
    nums.add(int(num1))
    nums.add(int(num2))
print(sorted(list(nums)))
 
Viimeksi muokattu:
Heh, äsken korjasin typon siitä printtaus-lausekkeesta. Noissa pythonin inline iffeissä pitää näköjään olla pakosta else-lohkokin. Tulee tosiaan pirun vähän käytettyä Pythonia mihinkään. Kokeiles vielä, kai tuon pitäs logiikaltaan olla ihan kondiksessa. Ei oo myöskään tällä henkkoht koneella pythonia, enkä jaksanut foorumia varten asentaa, niin en tullut ajaneeksi ite tota (sorit siitä :D ).

Moocin ohjelmoinnin perusteet Javalla on materiaalina minusta tosi hyvä, mutta hyviä Python-matskuja en osaa vinkata.

muoks. ja voi ristus sentään, pythonissahan True ja False kirjoitetaan isolla. Korjasin senkin. Ehken kirjoittele enää pythonia ajamatta koodia :D

KIITOS! Sain homman ratkaistua kun copy-pastesin koodin sivustolle ja hiukan laittelin sisennyksiä sivuston vaatimalla tavalla.
Seuraavassa tuskassa on taas kyse siitä, että en (ehkä) ymmärrä kysymystä.
Tehtävänannossa on 100 random luvun lista annettu valmiiksi ja kysymys kuuluu:
"Tee ohjelma, joka tulostaa suurimman eron kahden peräkkäisen luvun välillä listalla X."

Tarkoittaako tuo siis sitä, että listalla peräkkäiset luvut voidaan vähentää toisistaan siten, että isommasta aina vähennetään pienempi? Vaikea hahmottaa edes ilman koodia, että miten tuon yhtälön muotoilisi?
 
Tehtävänannossa on 100 random luvun lista annettu valmiiksi ja kysymys kuuluu:
"Tee ohjelma, joka tulostaa suurimman eron kahden peräkkäisen luvun välillä listalla X."

Tarkoittaako tuo siis sitä, että listalla peräkkäiset luvut voidaan vähentää toisistaan siten, että isommasta aina vähennetään pienempi? Vaikea hahmottaa edes ilman koodia, että miten tuon yhtälön muotoilisi?
Ei, kun sun pitää varmaan käydä tuo lista läpi ja vähentää aina käsiteltävästä luvusta edellinen. Eli nyt pitää hallita kahta eri indeksiä loopin sisällä.

Pythonissa ei taida olla natiivisti mitään indeksiperusteista for-looppia niin kuin Javassa, JS:ssä ja niin edelleen, mutta nähtävästi while-rakenteella onnistuu. Taas tuolla spoiler-tägeissä.

muoks. ja onnistuu indeksit muutenkin, spoilerin sisällä lisää.

Koodi:
indeksi = 1
suurin_erotus = 0
while indeksi < len(lista):
    erotus = lista[indeksi] - lista[indeksi - 1]
    if erotus > suurin_erotus:
        suurin_erotus = erotus
    indeksi += 1

Eli tuossa käsitellään listaa, jonka eka alkio on indeksissä 0 ja vika alkio indeksissä len(lista) - 1.

Luuppi aloitetaan listan tokasta alkiosta indeksissä 1, että saadaan mukaan nollassa oleva alkio. Sit vaan vähennetään aina kohdalla olevassa indeksissä oleva luku edellisestä ja pidetään muuttujassa ylhäällä suurinta erotusta. Suurinta erotusta päivitetään, jos uusi erotus on suurempi kuin edellinen.

En hahmota, pitäisikö tuossa ottaa huomioon mahdolliset negatiiviset luvut ja niiden keskenään vähennys. Jos pitää, niin sitten muutokset sen mukaan koodiinkin.

Ja Pythonissa on näköjään tuollainen enumerate-funktio, jota voi hyödyntää näissä indeksejä tarvitsevissa tehtävissä. Samoin tuon indeksiperusteisen luupin voi näköjään alustaa myös näin:
Koodi:
for i in range(len(lista)):
    tee_jotain

Rikoin nyt tuota edellistä, etten kirjoittele Pythonia ajamatta koodia, mutta saa tuosta varmaan ainakin ideaa :D
 
Sinuna opiskeliskin suosiolla moocin python-kurssin matskut läpi. Yläastetason matskuissa oiotaan ja skippaillaan ihan jo perusasioita melkeinpä aina.
 
"Tee ohjelma, joka tulostaa suurimman eron kahden peräkkäisen luvun välillä listalla X."

Alla one-liner -ehdotus. Eli muodostetaan listan peräkkäisistä luvuista pareja zip:n avulla. zip muodostaa argumenteista pareja, ja ne argumentit ovat kaksi listaa, joista ekasta puuttuu vika alkio ja tokasta eka alkio. Lopputuloksena uusi lista niistä pareista, joiden alkiot ovat tuple-tyyppiä eli pareja. Sitten luupataan ne kaikki parit läpi ja lasketaan niiden ero (eli erotuksen itseisarvo). Ja lopuksi otetaan listan maksimi max()-funktiolla. Tuo alkaa olla jo siinä ja siinä että alkaako luettavuus kärsiä. Ja varmasti kärsii jos noi list comprehensionit eivät ole tuttuja. En käyttäisi mihinkään tuota monimutkaisempaan tuota tyyliä. Mutta kannattaa opetella ehdottomasti zip:n käyttö, sekä nuo Pythonin jumalaiset tavat ottaa listasta joku sopiva pätkä alkioita.

Koodi:
max([abs(pair[0] - pair[1]) for pair in zip(values[:-1], values[1:])])
 
Sinuna opiskeliskin suosiolla moocin python-kurssin matskut läpi. Yläastetason matskuissa oiotaan ja skippaillaan ihan jo perusasioita melkeinpä aina.
@Stinde Peukkua tuolle lainatulle. Jos Moocilla kerran on joku Python-kurssi, niin kannattaa ehdottomasti käydä läpi. Ite tein aikanaan ne Java-tehtävät ja tykkäsin pirusti. Uskaltaa melkein sanoa, että paremmat matskut kuin yhdelläkään varsinaisella yliopistokurssilla on tullut vielä vastaan. Ei noita tehtäviä ole mieltä tehdä, jos ei ole kunnollisia eväitä tehtävien ratkaisuun.

Ymmärrät sitten paremmin noita kokeneempien Python-kirjoittelijoiden ratkaisujakin olettaen, että matskussa käydään noita Pythonille ominaisia temppuja läpi :)

muoks. vois itekin kurkata noita, ei tekis Python-reeni pahaa.
 
Tuo zip olikin itselleni ihan uusi juttu, jossain olin kyllä nähnyt että tuollainen on olemassa mutta ei ole tullut tutustuttua sen paremmin. Tuo olisi helpottanut erästä projektia jonkun verran, tein käytännössä vastaavan toiminnallisuuden itse asusta asti.

Pitäisiköhän itsekin opiskella joku python-mooc läpi, saattaisi oppia jotain kätevää kun tähän asti on oikestaan lähestulkoon itseoppinut googlen ja muutaman kohtalaisen heikon online-kurssin avulla.
 
Toinen juttu sitten, että ehkä zippeja sun muita alkaa vaan ihan proseduraalisesti käydä lista läpi eli laskea erotus 1. ja 2. luvun välillä, sitten seuraava ja verrata siihen asti isoimpaan ja jatkaa tätä sinne (n-1) - n asti.

Ei hirveesti väliä onko ekat ohjelmointitehtävät tehty "in a pythonic way"
 
Ei hirveesti väliä onko ekat ohjelmointitehtävät tehty "in a pythonic way"

Juuri näin. Alussa on tärkeää ottaa ihan perus for-luupit haltuun ja miettiä kielen erityisyyksiä myöhemmin. Kunhan mainitsen noista vaan kun yleensä itseäni kiinnostaa nähdä kun sama asia on ratkottu usealla eri tavalla.
 
Joo, minusta tuo kyseinen on ihan perinteinen ohjelmoinnin peruskurssien tehtävä, jossa tarkoitus on a) ymmärtää taulukot indekseineen, b) osata luupata taulukon indeksit läpi ja c) käsitellä samaan aikaan kahta eri indeksiä.

En tiedä oliko kysyjälle taulukotkaan kovin tuttuja kirjoitusten perusteella, ja tylsää tällaisia on tehdä, jos vaadittuja taustatietoja ei ole esitetty tai omaksuttu. Hyvä olisi myös ymmärtää taulukon (array) ja listan (list) erot tietorakenteina, vaikka Pythonissa listan toimintaperiaate näkyy olevankin aika joustava.

Tuosta askel eteenpäin olis sitten etsiä taulukosta jonkin arvon suurin esiintymä. Se vaatii taas vähän uuden logiikan ja/tai yhden uuden tietorakenteen omaksumista.
 
@Stinde Peukkua tuolle lainatulle. Jos Moocilla kerran on joku Python-kurssi, niin kannattaa ehdottomasti käydä läpi. Ite tein aikanaan ne Java-tehtävät ja tykkäsin pirusti. Uskaltaa melkein sanoa, että paremmat matskut kuin yhdelläkään varsinaisella yliopistokurssilla on tullut vielä vastaan. Ei noita tehtäviä ole mieltä tehdä, jos ei ole kunnollisia eväitä tehtävien ratkaisuun.

Ymmärrät sitten paremmin noita kokeneempien Python-kirjoittelijoiden ratkaisujakin olettaen, että matskussa käydään noita Pythonille ominaisia temppuja läpi :)

muoks. vois itekin kurkata noita, ei tekis Python-reeni pahaa.

Olen aikaisemmin käynyt sitä moocin java-kurssia läpi ja tykkäsin kovasti opetusmateriaalista ja mallivastauksista. Lisäksi kun hommat tehtiin "oikealla" koodausohjelmalla, niin helpotti tekemistä. Ei kyllä siinäkään taidot (tai aika) riittäneet kaiken oppimiseen ja ymmärtämiseen. Täytyy tutustua nyt tuohon python-versioon.
 
Kiitos hedelmällisestä keskustelusta ja kärsivällisistä vinkeistä. Tässä on välillä ollut sellainen fiilis, että on yrittänyt lukea netistä, että miten lapiota käytetään ja sitten tehtävänä on ollut kaivaa oja ja tosiosaajat ovat rientäneet paikalle auttamaan ja laittaneet kuvan kaivinkoneen ohjaamosta, että näillä ja näillä napeilla homma sujuu paljon helpommin/tehokkaammin. Täytyy nyt kuitenkin pidättäytyä näissä perusteissa, koska ilman niitä on mahdotonta rakentaa mitään niiden päälle.

Nyt oikein harmittaa, että olen jumissa varmaan jossain helpossa/älyttömässä paikassa:
Koodi:
for n in range(1,11):
    summa = 1
    suurin = 0
    while n != 1:
        if n%2 == 0:
            n = n//2
        else:
            n = 3*n+1
        summa += 1
        if summa > suurin:
            suurin = summa
print(suurin)

Tuo koodi liittyy Collatzin algoritmiin ja summan arvoksi tulostuu erilaisia lukuja ja tehtävänä olisi poimia niistä talteen se isoin ja tulostaa se. Nyt koodi kuitenkin pukkaa suurin-muuttujaan while-loopin viimeisen arvon eikä suurinta. Nyt jää joku täysin ilmiselvä huomaamatta.
 
Nyt oikein harmittaa, että olen jumissa varmaan jossain helpossa/älyttömässä paikassa:
Koodi:
for n in range(1,11):
    summa = 1
    suurin = 0
    while n != 1:
        if n%2 == 0:
            n = n//2
        else:
            n = 3*n+1
        summa += 1
        if summa > suurin:
            suurin = summa
print(suurin)

Tuo koodi liittyy Collatzin algoritmiin ja summan arvoksi tulostuu erilaisia lukuja ja tehtävänä olisi poimia niistä talteen se isoin ja tulostaa se. Nyt koodi kuitenkin pukkaa suurin-muuttujaan while-loopin viimeisen arvon eikä suurinta. Nyt jää joku täysin ilmiselvä huomaamatta.
Laita tuo "suurin = 0" ennen tuota for silmukkaa, muuten se nollaantuu joka kierros. Muuten näyttääkin samalta kuin oma ratkaisu.
 
Samalla tavallahan tuossa tulee tuo summa alustettua ykköseksi jokaisella iteraatiolla, eli senkin alustus luupin ulkopuolelle.

Nää on just näitä juttuja, joita alkuvaiheessa tulee ja jotka pitää hiffata :) Menevät kyllä kohtuu pian sit jo ihan automaationa oikein.

En oo Pythonia debuggaillut, mutta kannattaa opetella debuggerinkin käyttö jossain kohtaa. Sillä voi siis käydä askel askeleelta tuota luuppia läpi ja katsoa, mitä minkin muuttujan arvona milloinkin on. Se paljastais esim. tällaiset ongelmat hyvin nopsaan. Google kertoo debuggereista ja debuggauksesta lisää.
 
Onhan tuossa pari muutakin ongelmaa, kun nyt tarkasti katsoin. Olihan tämä tehtävä 3?
Eli tuossa for-loopissa pitäisi olla eri muuttuja kuin n, koska muuten ei käy kaikkia läpi. Ja tuo if pitäisi olla while:n ulkopuolella.
Tuossa mun:
Koodi:
max = 0
for i in range(1,1001):
    n=i
    x=1
    while n != 1:
        if n%2 == 0:
            n = n//2
        else:
            n = 3*n+1
        x += 1
    if (x>max):
        max=x
print(max)
 

Uusimmat viestit

Statistiikka

Viestiketjuista
259 325
Viestejä
4 504 514
Jäsenet
74 381
Uusin jäsen
Matimane

Hinta.fi

Back
Ylös Bottom