Ohjelmointi 1, syksy 2024, luento18

# L18

18. luento: ti 29.10.2024 klo 14:15-16:00: Tiedoston lukeminen ja käsittely

# git

Luentoesimerkkien haku versionhallinnasta

  • siirry hakemistoon johon haluat esimerkit

  • ekalla kertaa (tai jos olet ennen su 23.10 hakenut niin tuhoa vanha)

    git clone https://gitlab.jyu.fi/tie/ohj1/2024s/esimerkit.git .

    jatkossa samassa hakemistossa

    git pull
  • kopsi tuo hakemisto tai ainakin sinua kiinnostava alihakemisto toiseen paikkaan

  • periaatteessa tuonne syntyneen solutionin voi avata sellaisenaankin, mutta jos siihen tekee muutoksia, niin seuraavalla pull-komennolla tulee helposti konflikti

Mitä osataan?

Kurssin aikana sinun on tarkoitus oppia seuraavia asioita (osaamisen taso sovelletulla Bloomin asteikolla: 1=muistaa, 2=ymmärtää, 3=osaa soveltaa, 4=osaa analysoida, 5=osaa arvioida, 6=osaa luoda)

Siirrä alla osaamisesi (punainen pallukka) aina sitä vastaavalle kohdalle. Keltainen ruutu on tavoite johon tulisi päästä kurssin lopuksi. Ruksaa ensin muokkaa.

# goaltable2

Please to interact with this component.

Osattava asia123456
Rakenteisen ohjelmoinnin perusajatus o
Algoritminen ajattelu o
C#-kielen perusteet o
Peräkkäisyys o
Muuttujat o
Aliohjelmat ja funktiot o
Parametrin välitys o
Ehtolauseet o
Silmukat o
Taulukot o
Tiedostot ohjelmasta käytettynä o
Olioiden käyttö o
Yksikkötestit (TDD) o
Debuggerin käyttö o
Lukujärjestelmät, ASCII-koodi o
Rekursio o
Dokumentointi ja sen lukeminen o

Konvoluutio-demon malliohjelma

  • Demo 9, B1-3 harjoittelu
  • konvo.jar
    • lataa ja aja
      • java -jar konvo.jar
      • laita yläreunassa olevalle riville kuvan www-osoite ja lokaalilla levyllä olevan kuvan koko tiedostopolku
      • valitse kuinka monta kertaa mikäkin maskimatriisin ajetaan
      • paina Aja muunnokset

Filtteri

Filtteri on ohjelma, joka lukeee standardi syötettä (standard input, stdin) ja tekee riveille jotakin ja tulostaa sen standarditulosvirtaan (standard out, stdout).

# isoksi

Filtteri

using System;

public class Isoksi
{
    /// <summary>
    /// Tulostetaan isona syötettä
    /// </summary>
    public static void Main()
    {
        while (true)
        {
            string jono = Console.ReadLine();
            if (jono == null) break;
            Console.WriteLine(jono.ToUpper());
        }
    }
}

 

Tyypillisesti filtteriohjelmia ajetaan komentoriviltä ja niitä sovelletaan johonkin tiedostoon. Esimerkiksi tiedosto voisi olla:

# kissa
kissa istuu
puussa

 

Esimerkiksi syöte voidaan antaa suuntaamalla tulos jostakin tiedostosta:

# shell
dotnet-run isoksi.exe < kissa.txt

 

Edellä

dotnet-run

on erikseen vain TIMiin tehty komento, jotta käännetty ohjelma voidaan ajaa. Omassa koneessa vastaava tehtäisiin

dotnet run <kissa.txt

jos ohjelmalle on projekti ja ollaan projektin hakemistossa ks:

Jos ohjelma käännetään Windowsissa csc-komennolla, niin tällöin voi ajaa myös:

./Isoksi.exe <kissa.txt

Ohjelmalle voidaan putkittaa toisen ohjelman tulos, esim grep etsii tiedostosta rivit joilla toteutuu haluttu regular expresstion. Eli jos haluttaisiin muuttaa isoksi vain rivit joilla aluneprin esiintyy pienellä kirjoitettu kissa, se voitaisiin tehdä:

# shell2
grep kissa kissa.txt | dotnet-run isoksi.exe

 

Vastaavasti jos haluttaisiin näkyviin vain rivit, joissa muunnoksen jälkeen lukee KISSA, voitaisiin muunnos ajaa ensin ja sitten tehdä grepillä etsiminen:

# shell3
dotnet-run isoksi.exe < kissa.txt | grep KISSA

 

Hyvin yleistä on myös suunnata filtterin tulos tiedostoon:

# shell4
dotnet-run isoksi.exe < kissa.txt >isokissa.txt

 

# shell5
cat isokissa.txt

 

# shell6

Tehtävä 1

Anna shell komento, joilla saat tehtyä tiedoston vainisokissa.txt jossa on vain ne rivit, joilla alunperin esiintyi sana kissa.

# oma komento tähän
cat vainisokissa.txt

 

Tiedoston käsittely tiedostona

# tiedostoisoksi

Tiedosto isoksi

using System;
using System.IO;

public class TiedostoIsoksi
{
    public static void Main(string[] args)
    {
        // string dir = Directory.GetCurrentDirectory();
        // Console.WriteLine(dir);

        string nimi = "kissa.txt";
        if (args.Length > 0) nimi = args[0];


        string[] luetutRivit = File.ReadAllLines(nimi);

        foreach (string rivi in luetutRivit)
        {
            Console.WriteLine(rivi.ToUpper());
        }
    }

}

 

# kotustxt
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE kotus-sanalista SYSTEM "kotus-sanalista.dtd">
<!--
Copyright (C) Kotimaisten kielten tutkimuskeskus 2006
Kotimaisten kielten tutkimuskeskuksen nykysuomen sanalista, versio 1
Julkaistu 15.12.2006

Sanalista julkaistaan GNU LGPL -lisenssillä.
Lisenssiteksti luettavissa osoitteessa http://www.gnu.org/licenses/lgpl.html
-->

<kotus-sanalista>
<st><s>aakkonen</s><t><tn>38</tn></t></st>
<st><s>aakkosellinen</s><t><tn>38</tn></t></st>
<st><s>aakkosellisesti</s><t><tn>99</tn></t></st>
<st><s>aakkosellisuus</s><t><tn>40</tn></t></st>
<st><s>aakkosittain</s><t><tn>99</tn></t></st>
<st><s>aakkosjärjestys</s></st>
<st><s>aakkosnumeerinen</s></st>
<st><s>aakkostaa</s><t><tn>53</tn></t></st>
<st><s>aakkosto</s><t><tn>2</tn></t></st>
<st><s>aakkostus</s><t><tn>39</tn></t></st>
<st><s>aalloittain</s><t><tn>99</tn></t></st>
<st><s>aalloittainen</s><t><tn>38</tn></t></st>
<st><s>aalloittaisuus</s><t><tn>40</tn></t></st>
<st><s>aallokas</s><t><tn>41</tn><av>A</av></t></st>
<st><s>öykkäröinti</s><t><tn>5</tn><av>J</av></t></st>
<st><s>öylätti</s><t><tn>5</tn><av>C</av></t></st>
</kotus-sanalista>

 

# kainoisoksi

Etsitään vain sanat ja muutetaan ne isoksi

using System;
using System.IO;
using System.Text.RegularExpressions;

/// @author vesal
/// @version 1.11.2016
/// <summary>
/// Muutetaan Kotus sanalistan XML tiedostooa niin, että siellä olevat
/// sanat tulostetaan isolla.
/// Rivien muoto:
/// <pre>
///    <st><s>aakkonen</s><t><tn>38</tn></t></st>
/// </pre>
/// </summary>
public class Kaino
{
    /// <summary>
    ///
    /// </summary>
    public static void Main(string[] args)
    {
        string nimi = "kotus.xml";
        if (args.Length > 0) nimi = args[0];

        string[] luetutRivit = File.ReadAllLines(nimi);

        foreach (string rivi in luetutRivit)
        {
            // <st><s>aakkonen</s><t><tn>38</tn></t></st>
            Match match = Regex.Match(rivi, @".*<s>(.*)</s>.*", RegexOptions.IgnoreCase);

            if (match.Success)
            {
                string sana = match.Groups[1].Value;
                Console.WriteLine(sana.ToUpper());
            }
        }
    }

}

 

Hirsiauta

  • demo9 tehtävänä
  • tarkoitus auttaa hirsipuun pelaamisessa

Johdantoa

# jsauta

Hirsiapu

Tuota tarvittava regexp

//
  let s = "?????";
  let m = "[^]";
  let r = s.replaceAll("?", m);
  out.writeln(r);

 

Tiedosto

# sanattxt
APINA
KISSA
KETTU
KOIRA

 

Ohjelma joka käsittelee tiedostoa

# Plugin2
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

/// @author Omanimi
/// @version Päivämäärä
/// <summary>
/// <pre>
/// Aluksi kysyy
///     Anna tulos>?????
///     APINA
///     KISSA
///     KETTU
///     KOIRA
///     ...
///     Anna arvaamasi kirjain>A
///     Anna tulos >A???A
///     APINA
///     Anna arvaamasi kirjain>I
///     Anna tulos >A?I?A
///       
/// </pre>
/// </summary>
public class Hirsiauta
{
    /// <summary>
    /// 
    /// </summary>
    public static void Main(string[] args)
    {
        string nimi = "sanat.txt";
        if (args.Length > 0) nimi = args[0];
        string[] sanat = File.ReadAllLines(nimi);
        StringBuilder kaytetyt = new StringBuilder();
        string piste = ".";
        string tulos = "";

        while (true)
        {
            Console.Write($"Anna tulos ({tulos})>");
            string t = Console.ReadLine();
            if (t == null || t == "!") break;
            if (t != "") tulos = t;
            Jakauma jakauma = new Jakauma(kaytetyt.ToString());

            string maski = tulos.Replace("?", piste);
            Regex regex = new Regex("^" + maski + "$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            foreach (string rivi in sanat) // tutkitaan mitkä rivit täsmäävät
            {
                Match match = regex.Match(rivi);
                if (match.Success)
                {
                    Console.WriteLine(rivi);
                    jakauma.Add(rivi);
                }
            }
            Console.WriteLine(jakauma.ToString(5));

            Console.Write("Anna arvaamasi kirjain >");
            string kirjain = Console.ReadLine() ?? "";
            if (string.IsNullOrEmpty(kirjain) || kirjain == "!") break;
            kirjain = kirjain.ToUpper();
            kaytetyt.Append(kirjain);
            piste = "[^" + kaytetyt + "]"; // tulee esim [^AUO]  
        }

    }

}


/// <summary>
/// Jakaumalaskuri joka laskee kuinka paljon mitäkin kirjainta esiintyy.
/// Alustuksessa voidaan antaa mitä kirjaimia ei oteta huomioon.
/// </summary>
public class Jakauma
{
    // TODO: tähän sopiva attribuutti tai attribuutit jotta saadaan laskettua
    // ReSharper disable once NotAccessedField.Local
    private readonly string eiLisata;

    /// <summary>
    /// Alustaan jakaumalaskuri niin, että laskuihin ei oteta annettua kirjainjoukkoa
    /// </summary>
    /// <param name="eiLisata">mitä kirjaimia ei lasketa mukaan</param>
    public Jakauma(string eiLisata = "")
    {
        this.eiLisata = eiLisata;
    }

    /// <summary>
    /// Lisätään rakenteesen yksi kirjain jollei se ole kielletyissä
    /// </summary>
    /// <param name="c">lisättävä kirjain</param>
    /// <example>
    /// <pre name="test">
    ///     Jakauma jakauma = new Jakauma();
    ///     jakauma.Add('a');
    ///     jakauma.Add('i');
    ///     jakauma.Add('a');
    ///     jakauma.ToString(4) === "a:2 i:1";
    /// </pre>
    /// </example>
    public void Add(char c)
    {
        // TODO: tee kuten kommenteissa on ja niin että testit menevät läpi
    }


    /// <summary>
    /// Lisätään kaikki jonon kirjaimet jotka eivät ole kielletyissä
    /// </summary>
    /// <param name="rivi">jono jonka kirjaimet lisätään jakaumaan</param>
    /// <example>
    /// <pre name="test">
    ///     Jakauma jakauma = new Jakauma("ei ");
    ///     jakauma.Add("kissa ei istu puussa");
    ///     jakauma.ToString(10) === "s:5 u:3 a:2 k:1 t:1 p:1";
    /// </pre>
    /// </example>
    public void Add(string rivi)
    {
        // TODO: lisää kirjaimet
    }


    /// <summary>
    /// Palautetaan jakauma merkkijonona jossa on n ensimmäistä yleisintä kirjainta
    /// </summary>
    /// <param name="n">kuinka monta kirjainta laitetaan jonoon</param>
    /// <returns></returns>
    /// <example>
    /// <pre name="test">
    ///     Jakauma jakauma = new Jakauma(" ");
    ///     jakauma.Add("kissa ei istu puussa");
    ///     jakauma.ToString(2) === "s:5 i:3";
    /// </pre>
    /// </example>
    public string ToString(int n)
    {
        return "S:5 I:3";
    }

}

 

Demoihin käytettyjen aikojen laskeminen

  • Aika.cs - esimerkki, jossa yhdistetään kahden erilaisen tiedoston sisältöä
  • Syksyn 2019 videot: Osa 1 MP4 alkuperäinen
  • Exceliin:
    • copy/paste syntynyt tiedosto
    • lisätään rpist,raika (round)
    • aluelle nimeksi data
    • filtteriksi
    • lisätään pivot data-alueesta
    • riveiksi demo ja rpist
    • sarkkeiksi raika
    • sisällöksi count(raika)

These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.