Pieniä kysymyksiä ohjelmoinnista

Kokeillaanpas, saisiko täällä apua, kun koululle ei hetkeen pääse ohjaukseen.

Eli tarkoituksena on tehdä peli Jypeli-pelimoottorilla. Ongelmana on, että törmäyksen lisäämisen jälkeen peli kaatuu heti ja tulee ilmoitus System.NullReferenceException: 'Colliding object must not be null'. Ennen törmäyksen lisäämistä tuli sama virheilmoitus, kun yritti liikuttaa hahmoa A ja D -näppäimillä.

Eli mitä ihmettä tarkoittaa, kun fysiikkaolio on null ja miten tuon saa korjattua? Fysiikkaolioita on tällä hetkellä kaksi, pommi ja hahmo. Koodi on aivan kesken ja kaikki eivät vielä toimi, mutta olisi kiva saada ohjelma edes kääntymään tässä vaiheessa. Varoituksia tai virheitä Visual Studio ei anna ennen kaatumista.

using System;
using System.Collections.Generic;
using Jypeli;
using Jypeli.Assets;
using Jypeli.Controls;
using Jypeli.Widgets;

public class FysiikkaPeli7 : PhysicsGame
{
Vector NopeusVasen = new Vector(200, 0);
Vector NopeusOikea = new Vector(-200, 0);


PhysicsObject hahmo;
PhysicsObject pommi;
PhysicsObject alaReuna;

public override void Begin()
{
AsetaOhjaimet();
LuoKentta();
Kamera();
LuoAikaLaskuri();




int i = 0;
while (i < 10)
{
int sade = RandomGen.NextInt(5, 20);
double x = RandomGen.NextDouble(Level.Left, Level.Right);
double y = RandomGen.NextDouble(Level.Bottom, Level.Top);
PhysicsObject pommi = LuoPommi(x);
Add(pommi);
i++;
}

}
void AsetaOhjaimet()
{
PhoneBackButton.Listen(ConfirmExit, "Lopeta peli");
Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
Keyboard.Listen(Key.A, ButtonState.Pressed, AsetaNopeus, "Liikuttaa hahmoa vasemmalle", hahmo, NopeusVasen);
Keyboard.Listen(Key.A, ButtonState.Released, AsetaNopeus, "seis", hahmo, Vector.Zero);
Keyboard.Listen(Key.D, ButtonState.Pressed, AsetaNopeus, "Liikuttaa hahmoa oikealle", hahmo, NopeusOikea);
Keyboard.Listen(Key.D, ButtonState.Released, AsetaNopeus, "seis", hahmo, Vector.Zero);
}
void LuoKentta()
{
Surface alaReuna = Surface.CreateBottom(Level);
Add(alaReuna);
Gravity = new Vector(0.0, -700.0);
hahmo = LuoHahmo();
AddCollisionHandler(pommi, alaReuna, CollisionHandler.DestroyObject);


}
PhysicsObject LuoHahmo()
{
PhysicsObject hahmo = new PhysicsObject(40.0, 40.0);
hahmo.X = 0;
hahmo.Y = -378;
hahmo.Shape = Shape.Triangle;
Add(hahmo);
return hahmo;
}
void Kamera()
{
Camera.Zoom(0.9);
}

void AsetaNopeus(PhysicsObject hahmo, Vector nopeus)
{
hahmo.Velocity = nopeus;
}

void LuoAikaLaskuri()
{
Timer aikaLaskuri = new Timer();
aikaLaskuri.Start();

Label aikaNaytto = new Label();
aikaNaytto.TextColor = Color.Red;
aikaNaytto.DecimalPlaces = 1;
aikaNaytto.BindTo(aikaLaskuri.SecondCounter);
aikaNaytto.BorderColor = Color.Red;
aikaNaytto.Color = Color.Gray;
aikaNaytto.X = Screen.Left + 100;
aikaNaytto.Y = Screen.Top - 50;

Add(aikaNaytto);
}
PhysicsObject LuoPommi(double x)
{
PhysicsObject pommi = new PhysicsObject(40, 40);
pommi.Shape = Shape.Circle;
pommi.X = x;
pommi.Y = 300;
pommi.Mass = 200;
Add(pommi);
return pommi;
}

}
 
Kokeillaanpas, saisiko täällä apua, kun koululle ei hetkeen pääse ohjaukseen.

Eli tarkoituksena on tehdä peli Jypeli-pelimoottorilla. Ongelmana on, että törmäyksen lisäämisen jälkeen peli kaatuu heti ja tulee ilmoitus System.NullReferenceException: 'Colliding object must not be null'. Ennen törmäyksen lisäämistä tuli sama virheilmoitus, kun yritti liikuttaa hahmoa A ja D -näppäimillä.

Eli mitä ihmettä tarkoittaa, kun fysiikkaolio on null ja miten tuon saa korjattua? Fysiikkaolioita on tällä hetkellä kaksi, pommi ja hahmo. Koodi on aivan kesken ja kaikki eivät vielä toimi, mutta olisi kiva saada ohjelma edes kääntymään tässä vaiheessa. Varoituksia tai virheitä Visual Studio ei anna ennen kaatumista.

using System;
using System.Collections.Generic;
using Jypeli;
using Jypeli.Assets;
using Jypeli.Controls;
using Jypeli.Widgets;

public class FysiikkaPeli7 : PhysicsGame
{
Vector NopeusVasen = new Vector(200, 0);
Vector NopeusOikea = new Vector(-200, 0);


PhysicsObject hahmo;
PhysicsObject pommi;
PhysicsObject alaReuna;

public override void Begin()
{
AsetaOhjaimet();
LuoKentta();
Kamera();
LuoAikaLaskuri();




int i = 0;
while (i < 10)
{
int sade = RandomGen.NextInt(5, 20);
double x = RandomGen.NextDouble(Level.Left, Level.Right);
double y = RandomGen.NextDouble(Level.Bottom, Level.Top);
PhysicsObject pommi = LuoPommi(x);
Add(pommi);
i++;
}

}
void AsetaOhjaimet()
{
PhoneBackButton.Listen(ConfirmExit, "Lopeta peli");
Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
Keyboard.Listen(Key.A, ButtonState.Pressed, AsetaNopeus, "Liikuttaa hahmoa vasemmalle", hahmo, NopeusVasen);
Keyboard.Listen(Key.A, ButtonState.Released, AsetaNopeus, "seis", hahmo, Vector.Zero);
Keyboard.Listen(Key.D, ButtonState.Pressed, AsetaNopeus, "Liikuttaa hahmoa oikealle", hahmo, NopeusOikea);
Keyboard.Listen(Key.D, ButtonState.Released, AsetaNopeus, "seis", hahmo, Vector.Zero);
}
void LuoKentta()
{
Surface alaReuna = Surface.CreateBottom(Level);
Add(alaReuna);
Gravity = new Vector(0.0, -700.0);
hahmo = LuoHahmo();
AddCollisionHandler(pommi, alaReuna, CollisionHandler.DestroyObject);


}
PhysicsObject LuoHahmo()
{
PhysicsObject hahmo = new PhysicsObject(40.0, 40.0);
hahmo.X = 0;
hahmo.Y = -378;
hahmo.Shape = Shape.Triangle;
Add(hahmo);
return hahmo;
}
void Kamera()
{
Camera.Zoom(0.9);
}

void AsetaNopeus(PhysicsObject hahmo, Vector nopeus)
{
hahmo.Velocity = nopeus;
}

void LuoAikaLaskuri()
{
Timer aikaLaskuri = new Timer();
aikaLaskuri.Start();

Label aikaNaytto = new Label();
aikaNaytto.TextColor = Color.Red;
aikaNaytto.DecimalPlaces = 1;
aikaNaytto.BindTo(aikaLaskuri.SecondCounter);
aikaNaytto.BorderColor = Color.Red;
aikaNaytto.Color = Color.Gray;
aikaNaytto.X = Screen.Left + 100;
aikaNaytto.Y = Screen.Top - 50;

Add(aikaNaytto);
}
PhysicsObject LuoPommi(double x)
{
PhysicsObject pommi = new PhysicsObject(40, 40);
pommi.Shape = Shape.Circle;
pommi.X = x;
pommi.Y = 300;
pommi.Mass = 200;
Add(pommi);
return pommi;
}

}
Luo kenttä käyttää pommia ennen kuin yhtään on luotu?
 
Luo kenttä käyttää pommia ennen kuin yhtään on luotu?
Kiitoksia! Lisäsin pommi = LuoPommi(1) ja ohjelma kääntyi. Ongelmana on kuitenkin yhä, että hahmon liikuttaminen, eli A ja D näppäimet kaatavat pelin. Virheilmoitus on samankaltainen kuin edellisessä. Mietin, että aiheuttavatko vektorit tässä tapauksessa ongelmia. :think:

PteTFnC.png
 
Kiitoksia! Lisäsin pommi = LuoPommi(1) ja ohjelma kääntyi. Ongelmana on kuitenkin yhä, että hahmon liikuttaminen, eli A ja D näppäimet kaatavat pelin. Virheilmoitus on samankaltainen kuin edellisessä. Mietin, että aiheuttavatko vektorit tässä tapauksessa ongelmia. :think:

PteTFnC.png
korjaantuisikohan jos luot noi listenerit vasta kentän jälkeen. eli:

AsetaOhjaimet();
LuoKentta();
Kamera();
LuoAikaLaskuri();


muotoon

LuoKentta();
Kamera();
LuoAikaLaskuri();

AsetaOhjaimet();

Noitahan ei (paitsi backia) tarvita kuin vasta luodussa kentässä. Voi ehkä olla ylempänäkin mutta en näe haittaa että se on alimmaisena. Hahmohan luodaan vasta kentän mukana ja nyt asetat kuuntelijat PhysicsObject hahmo = null; muuttujalle etkä hahmo = LuoHahmo(); muutujalle
 
korjaantuisikohan jos luot noi listenerit vasta kentän jälkeen. eli:

AsetaOhjaimet();
LuoKentta();
Kamera();
LuoAikaLaskuri();


muotoon

LuoKentta();
Kamera();
LuoAikaLaskuri();
AsetaOhjaimet();

Noitahan ei (paitsi backia) tarvita kuin vasta luodussa kentässä. Voi ehkä olla ylempänäkin mutta en näe haittaa että se on alimmaisena. Hahmohan luodaan vasta kentän mukana ja nyt asetat kuuntelijat PhysicsObject hahmo = null; muuttujalle etkä hahmo = LuoHahmo(); muutujalle
Suuret kiitokset taas! Nyt toimii ja pääsee eteenpäin projektissa :)
 
Kokeillaanpas, saisiko täällä apua, kun koululle ei hetkeen pääse ohjaukseen.

Eli tarkoituksena on tehdä peli Jypeli-pelimoottorilla. Ongelmana on, että törmäyksen lisäämisen jälkeen peli kaatuu heti ja tulee ilmoitus System.NullReferenceException: 'Colliding object must not be null'. Ennen törmäyksen lisäämistä tuli sama virheilmoitus, kun yritti liikuttaa hahmoa A ja D -näppäimillä.

Eli mitä ihmettä tarkoittaa, kun fysiikkaolio on null ja miten tuon saa korjattua? Fysiikkaolioita on tällä hetkellä kaksi, pommi ja hahmo. Koodi on aivan kesken ja kaikki eivät vielä toimi, mutta olisi kiva saada ohjelma edes kääntymään tässä vaiheessa. Varoituksia tai virheitä Visual Studio ei anna ennen kaatumista.
Null on monissa kielissä olioiden oletusarvo ennen kuin niille annetaan jokin muu arvo. NullReferenceException tulee normaalisti, kun yrittää käyttää jotain olion metodia tai kenttää ennen kuin on antanut oliolle mitään arvoa. Tässä tapauksessa Jypeli ilmeisesti tarkistaa törmäävät kappaleet ja varoittaa, jos ainakin toinen on null, koska null ei oikein voi törmätä mihinkään. Ratkaisu tämänkaltaisiin ongelmiin on tietenkin antaa oliolle jokin muu arvo kuin null ennen kuin yrittää käyttää oliota. Tämä nyt taisikin jo ratketa, mutta ehkä tästä on hyötyä jatkoa ajatellen.
 
Josko täältä löytyisi apua tähän ongelmaan.
Tarkoituksena lisätä kappale tuohon ArrayList:iin, mutta jostain syystä se ei sinne mene tai sitten joku muu kusee ko. koodissa.

Koodi:
public class Main {

   public static void main(String[] args) {

       Scanner input = new Scanner(System.in);
       String inputFromUser, tr, art;
     
       while(true) {
           System.out.print("\nEnter desired action: ");
           inputFromUser = input.nextLine();
           switch(inputFromUser) {
               case "1":
                   System.out.println("---------------------");
                   System.out.println("Add Track to Playlist");
                   System.out.println("---------------------");
                   System.out.print("Enter track name: ");
                   tr = input.nextLine();
                   System.out.print("Enter artist: ");
                   art = input.nextLine();
                   Playlist case1 = new Playlist(tr, art);
                   System.out.println(tr + " " + "by " + art + " added!");
                   break;         
               default:
                   System.out.println("Invalid input!");
     
           }
       }
   }
}

Koodi:
public class Songs {
   
   private String name;
   private String artist;
   private int lenght;
   
   public Songs(String name, String artist) {
       this.name = name;
       this.artist = artist;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public String getArtist() {
       return artist;
   }

   public void setArtist(String artist) {
       this.artist = artist;
   }

   public int getLenght() {
       return lenght;
   }

   public void setLenght(int lenght) {
       this.lenght = lenght;
   }
   
   public String toString() {
       return this.name + " by " + this.artist + "\n";
   }
}

Koodi:
import java.util.ArrayList;
import java.util.Collections;

public class Playlist {
   
   ArrayList <Songs> playlist = new ArrayList <>();

   public Playlist() {

   }
   
   public Playlist(String name, String artist) {
       playlist.add(new Songs(name, artist));

   }
   
   public String toString() {
       String output = "";
       for (int i = 0; i < playlist.size(); i++) {
       output = output + playlist.get(i);
       }
       return output;

   }
}
 
Josko täältä löytyisi apua tähän ongelmaan.
Tarkoituksena lisätä kappale tuohon ArrayList:iin, mutta jostain syystä se ei sinne mene tai sitten joku muu kusee ko. koodissa.

Koodi:
public class Main {

   public static void main(String[] args) {

       Scanner input = new Scanner(System.in);
       String inputFromUser, tr, art;
    
       while(true) {
           System.out.print("\nEnter desired action: ");
           inputFromUser = input.nextLine();
           switch(inputFromUser) {
               case "1":
                   System.out.println("---------------------");
                   System.out.println("Add Track to Playlist");
                   System.out.println("---------------------");
                   System.out.print("Enter track name: ");
                   tr = input.nextLine();
                   System.out.print("Enter artist: ");
                   art = input.nextLine();
                   Playlist case1 = new Playlist(tr, art);
                   System.out.println(tr + " " + "by " + art + " added!");
                   break;        
               default:
                   System.out.println("Invalid input!");
    
           }
       }
   }
}

Koodi:
public class Songs {
  
   private String name;
   private String artist;
   private int lenght;
  
   public Songs(String name, String artist) {
       this.name = name;
       this.artist = artist;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public String getArtist() {
       return artist;
   }

   public void setArtist(String artist) {
       this.artist = artist;
   }

   public int getLenght() {
       return lenght;
   }

   public void setLenght(int lenght) {
       this.lenght = lenght;
   }
  
   public String toString() {
       return this.name + " by " + this.artist + "\n";
   }
}

Koodi:
import java.util.ArrayList;
import java.util.Collections;

public class Playlist {
  
   ArrayList <Songs> playlist = new ArrayList <>();

   public Playlist() {

   }
  
   public Playlist(String name, String artist) {
       playlist.add(new Songs(name, artist));

   }
  
   public String toString() {
       String output = "";
       for (int i = 0; i < playlist.size(); i++) {
       output = output + playlist.get(i);
       }
       return output;

   }
}
älä tee uutta playlistiä tuolla whilessa vaan uus song ja lisää se .add llä vanhaan playlistiin
 
Ok, mutta voitko hieman näyttää miten?
Ei ihan riitä vielä tietotaito.
Tuon:
Playlist case1 = new Playlist(tr, art);
tilalle
playlist.add(new Songs(tr, art));

About noin. sun playlistin kuulu sisältää songs olioita niin tuossa siihen laitetaan semmonen
 
Ongelmaksi tulee virhe "playlist cannot be resolved"
Tuo virhe johtuu kaiketi siitä, ettet ole aiemmin luonut vielä missään Playlistiä. Sinun pitää luoda sellainen ennen käyttöä ja mielellään while-silmukan ulkopuolella, ettet törmää taas samaan ongelmaan kuin aiemmin.
 
Tee ensin PlayListille add-metodi, jolla lisäät kappaleet. Ei lisätä vaan konstruktorissa.
 
Samalla tavalla kuin

public void setName(String name) {
this.name = name;
}

Songs-luokassa. (Song?)

Tee metodi, joka ei palauta mitään (void).
Nimeksi voi laittaa add (setNamen sijaan).
Parametreiksi name ja artist.
Luo PlayList ihan ylhäällä, whilen ulkopuolella, mutta main-metodissa, tyyliin PlayList pl = new PlayList();
Käytä pl-instanssin add-metodia lisäämään kappaleet yksi kerrallaan. Siellä missä nyt teet koko ajan uusia PlayList-olioita, teetkin lisäyksen kutsumalla pl:n add-metodia - jonka juuri teit.
Voit nimetä sen muuksikin kuin pl, mutta case1 ei ole parempi nimi.. Ehkä userPlayList ?

--

Suosittelen, että hankit kirjan tai katsot sarjan youtube-videoita (en osaa löytää niitä, olen kirjaihmisiä). Tämäkin lähestymistapa voi toimia, mutta se on ainakin hitaampaa. Nyt meni ainakin päivä yhdessä ohjelmassa :(
Tosin itse tekemällä oppii parhaiten.
 
Tässä kohtaa paras tapa olisi jälleen materiaalina esimerkiksi www.mooc.fi , jossa on tarjolla myös apukanava (joka tosin auttaa ensisijaisesti vain Mooc-kurssin omissa tehtävissä), sillä tällaisten läpikäyminen foorumilla on harvinaisen hidasta ja epäkätevää.
 
public Playlist(String name, String artist) { playlist.add(new Songs(name, artist)); }

Tuon konstruktorin tyylillä

public add(String name, String artist) { playlist.add(new Songs(name, artist)); }

public add(Songs song) { playlist.add(song); }

jompi kumpi tai molemmat.
 
Kiitoksia kaikille avusta.
Ei se nyt vieläkään tosin toimi, mutta palaan takaisin opiskelun pariin.
 
Kiitoksia kaikille avusta.
Ei se nyt vieläkään tosin toimi, mutta palaan takaisin opiskelun pariin.
Tässä hieman siistittynä nuo sun luokat ja malli miten saat biisin listaan:

Koodi:
public class Sample {

    public static void main(String[] args) {
        
        Scanner scanner = new Scanner(System.in);
        String userSelection, track, artist;
        
        // Luo soittolista täällä
        Playlist playlist = new Playlist();
        
        while (true){
            
            System.out.println("Add song (1)");
            System.out.println("Show playlist (2)");
            System.out.println("Exit (3)");
            System.out.print("Enter desired action: ");
            userSelection = scanner.nextLine();
            
            switch (userSelection){
                case "1":
                    System.out.print("Enter track name: ");
                    track = scanner.nextLine();
                    System.out.print("Enter artist: ");
                    artist = scanner.nextLine();
                    // Luo biisi täällä
                    Song song = new Song(track, artist);
                    // Kutsu Playlist-luokan metodia, joka lisää biisin listaan
                    playlist.addToList(song);
                    break;
                case "2":
                    // Tulostetaan biisit
                    System.out.print(playlist.toString());
                    break;
                case "3":
                    // Täällä varmaan haluat poistua while-loopista. En pureskele ihan valmiiksi.
                    break;
                default:
                    break;
            }
        }
    }
}
Koodi:
public class Song {
    
    private String name;
    private String artist;
    
    public Song(String name, String artist){
        this.name = name;
        this.artist = artist;
    }
    
    @Override
    public String toString(){
        return name + " by " + artist;
    }
}
Koodi:
public class Playlist {
    
    private List<Song> songs;
    
    public Playlist(){
        this.songs = new ArrayList<>();
    }
    
    public void addToList(Song song){
        this.songs.add(song);
    }
    
    @Override
    public String toString(){
        String output = "";
        for (int i = 0; i < songs.size(); i++){
            output += (songs.get(i) + "\n");
        }
        return output;
    }
}
 
Tässä hieman siistittynä nuo sun luokat ja malli miten saat biisin listaan:

Koodi:
public class Sample {

    public static void main(String[] args) {
      
        Scanner scanner = new Scanner(System.in);
        String userSelection, track, artist;
      
        // Luo soittolista täällä
        Playlist playlist = new Playlist();
      
        while (true){
          
            System.out.println("Add song (1)");
            System.out.println("Show playlist (2)");
            System.out.println("Exit (3)");
            System.out.print("Enter desired action: ");
            userSelection = scanner.nextLine();
          
            switch (userSelection){
                case "1":
                    System.out.print("Enter track name: ");
                    track = scanner.nextLine();
                    System.out.print("Enter artist: ");
                    artist = scanner.nextLine();
                    // Luo biisi täällä
                    Song song = new Song(track, artist);
                    // Kutsu Playlist-luokan metodia, joka lisää biisin listaan
                    playlist.addToList(song);
                    break;
                case "2":
                    // Tulostetaan biisit
                    System.out.print(playlist.toString());
                    break;
                case "3":
                    // Täällä varmaan haluat poistua while-loopista. En pureskele ihan valmiiksi.
                    break;
                default:
                    break;
            }
        }
    }
}
Koodi:
public class Song {
  
    private String name;
    private String artist;
  
    public Song(String name, String artist){
        this.name = name;
        this.artist = artist;
    }
  
    @Override
    public String toString(){
        return name + " by " + artist;
    }
}
Koodi:
public class Playlist {
  
    private List<Song> songs;
  
    public Playlist(){
        this.songs = new ArrayList<>();
    }
  
    public void addToList(Song song){
        this.songs.add(song);
    }
  
    @Override
    public String toString(){
        String output = "";
        for (int i = 0; i < songs.size(); i++){
            output += (songs.get(i) + "\n");
        }
        return output;
    }
}

Nyt täytyy nostaa hattua, kiitos!
Väheksymättä kenenkään muun apua.

Vähän tuo rakenne hukassa, mutta eiköhän se tuosta opiskelemalla selkene.
 
Toimiiko joku hakukone html(5) iframesta tms. upotuksesta niin, että hakutulokset avautuu uuteen tabiin tai ikkunaan?
 
Toimiiko joku hakukone html(5) iframesta tms. upotuksesta niin, että hakutulokset avautuu uuteen tabiin tai ikkunaan?

Miksi iframe?

itse pistäisin get metodilla google.com/search

HTML:
<form method="get" action="http://www.google.com/search" target="_blank">
    <input name="q" size="40" maxlength="2000" type="text" placeholder="google haku">
    <input type="submit" value="hae">
</form>
 
Tarkoitus olisi laittaa hakusanoja valmiiksi hakukenttään tai jopa suoraan hakusivu noilla sanoilla jonkinlaisen elementin sisään, mutta tuo taitaa olla kaikissa estetty?

DuckDuckGo Search Box

Duckduckgolla saikin haun uuteen tabiin, kun lisää &kn=1 url optioihin.
 
Tarkoitus olisi laittaa hakusanoja valmiiksi hakukenttään tai jopa suoraan hakusivu noilla sanoilla jonkinlaisen elementin sisään, mutta tuo taitaa olla kaikissa estetty?

DuckDuckGo Search Box

Duckduckgolla saikin haun uuteen tabiin, kun lisää &kn=1 url optioihin.
En oikeen ymmärrä minne tässä iframe tarvitaan.. :confused:
Esim edelliseen viestin koodin kun lisää inputille value atribuutin ja sille arvoksi hakusanan. Silloin hakukenttä on ns. valmiiksi täytetty.
Jos hakukone sivun x-frame-options headeri on SAMEORIGIN, niin iframe ei ole vaihtoehto. iframe on muutenkin aika kyseenalainen nykyään (Clickjacking yms...)

Mutta lähes jokaisen hakukoneen saa omalle sivulle formiin, taget atribuutin arvoksi "_blank" jolloin haku aukeaa uuteen välilehteen.
esimerkki -> Edit fiddle - JSFiddle
 
Bash-kysymys. Kuinka saan poimittua alla olevan tyylisistä tiedostoista numeron 14, jos sellainen on määritelty? Numero on aina kahden oikeanpuoleisimman pisteen välissä.

01-testi.tiedosto.kuva_autosta.14.jpg

Edit:
Löysin sattumalta komennon rev, joka kääntää tiedostonimen takaperin. Nyt pystyn valitsemaan toiseksi enimmäisen pisteillä erotetun kentän, joka vastaa toiseksi viimeistä kenttää, kun tiedostonimeä ei ole käännetty takaperin.

NUMBER="$(echo "${FILENAME}" | rev cut -d '.' -f 2 | rev)"
 
Viimeksi muokattu:
Bash-kysymys. Kuinka saan poimittua alla olevan tyylisistä tiedostoista numeron 14, jos sellainen on määritelty? Numero on aina kahden oikeanpuoleisimman pisteen välissä.

01-testi.tiedosto.kuva_autosta.14.jpg

Edit:
Löysin sattumalta komennon rev, joka kääntää tiedostonimen takaperin. Nyt pystyn valitsemaan toiseksi enimmäisen pisteillä erotetun kentän, joka vastaa toiseksi viimeistä kenttää, kun tiedostonimeä ei ole käännetty takaperin.

NUMBER="$(echo "${FILENAME}" | rev cut -d '.' -f 2 | rev)"

Keksitkin jo ratkaisun, mutta tässä silti vaihtoehtoinen tapa. Ei ihan oneliner mutta ei tarvitse ulkoisia komentoja:
Koodi:
IFS=. read -a FN_SPLIT <<< "${FILENAME}"
NUMBER=${FN_SPLIT[-2]}
 
Keksitkin jo ratkaisun, mutta tässä silti vaihtoehtoinen tapa. Ei ihan oneliner mutta ei tarvitse ulkoisia komentoja:
Koodi:
IFS=. read -a FN_SPLIT <<< "${FILENAME}"
NUMBER=${FN_SPLIT[-2]}
Ja jos halutaan mennä siitä, missä aita ei (yleensä) ole matalin, niin ainahan ovat säännölliset lausekkeet.
Koodi:
FILENAME="01-testi.tiedosto.kuva_autosta.14.12.jpg"
REGEX="\.([0-9]+)\.[^.]*$"
if [[ $FILENAME =~ $REGEX ]]
then
        NUMBER="${BASH_REMATCH[1]}"
else
        NUMBER="error"
fi
echo "NUMBER = $NUMBER"
 
Ja jos halutaan mennä siitä, missä aita ei (yleensä) ole matalin, niin ainahan ovat säännölliset lausekkeet.
Koodi:
FILENAME="01-testi.tiedosto.kuva_autosta.14.12.jpg"
REGEX="\.([0-9]+)\.[^.]*$"
if [[ $FILENAME =~ $REGEX ]]
then
        NUMBER="${BASH_REMATCH[1]}"
else
        NUMBER="error"
fi
echo "NUMBER = $NUMBER"

regular_expressions.png
 
Mutta lähes jokaisen hakukoneen saa omalle sivulle formiin, taget atribuutin arvoksi "_blank" jolloin haku aukeaa uuteen välilehteen.
esimerkki -> Edit fiddle - JSFiddle
Tuossa oli ajatuskatko, formit ei auta valmiiksi täytettyihin hakulinkkeihin verrattuna, kun molemmissa tarvittavat tiedot on kahden klikin päässä, mutta saan näemmä tarvittavat tiedot suoraan samalle sivulle Discogs APIn kautta joka on parempi kuin hakutulosten upotus.
 
Tiedä osuuko täysin oikeaan topiciin, mutta täällä varmaan tapaa laajimman asiantuntija kunnan :) Olisi tarvetta saada Outlook 365 kalenterista työpaikalla vedettyä useamman eri käyttäjän kalenterit yhdeksi kalenteriksi tai saada automaattisesti excel päivittämään monen ihmisen kalentereista tietoja excel asiakirjaan.

Ajattelin täällä kysellä alkuunsa onko tuo edes etäisesti mahdollista vai pitääkö unohtaa koko homma?
 
Tiedä osuuko täysin oikeaan topiciin, mutta täällä varmaan tapaa laajimman asiantuntija kunnan :) Olisi tarvetta saada Outlook 365 kalenterista työpaikalla vedettyä useamman eri käyttäjän kalenterit yhdeksi kalenteriksi tai saada automaattisesti excel päivittämään monen ihmisen kalentereista tietoja excel asiakirjaan.

Ajattelin täällä kysellä alkuunsa onko tuo edes etäisesti mahdollista vai pitääkö unohtaa koko homma?

Kuulostaa Calendar Group hommilta... Kannattaa mennä tonne ohjelmisto palstalle kyselemään office guruja.
Microsoft Office
 
Miten saa Javascriptin toimimaan jQueryn loadilla ladatussa elementissä?

Ajetaan index.php, ja kaikki toimii niin kuin pitääkin. Painetaan nappia, joka lataa testaus2.php:n sisällön div-elementtiin. Sisältö ilmestyy, mutta popper.js ei enää toimi.

Koodit:

index.php:
HTML:
<!DOCTYPE html>

<html lang="en">
    <head>
        <title>Testi</title>
        <link rel="stylesheet" href="css/bootstrap.css">
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    </head>
    <body>
        <div class="container-fluid">
            <div class="row" id="testaus">
                <?php include_once 'testaus.php'; ?>
            </div>
            <button>Nappi</button>
        </div>

        

        <script src="jquery/jquery-3.3.1.js"></script>
        <script src="popper/popper.js"></script>
        <script src="js/bootstrap.js"></script>

        <script>
            $(document).ready(function () {
                $('[data-toggle="popover"]').popover({html: true});
            });
        </script>

        <script>
            $(document).ready(function () {
                $("button").click(function () {
                    $("#testaus").load("testaus2.php");
                });
            });
        </script>

    </body>
</html>

testaus.php:
PHP:
<?php

echo "<p><a href='javascript://' data-toggle='popover' data-trigger='focus' 
data-content='<a href=\"https://bbs.io-tech.fi/\" target=\"_blank\">TechBBS</a>'>TechBBS</a></p>";

?>

testaus2.php:
PHP:
<?php

echo "<p><a href='javascript://' data-toggle='popover' data-trigger='focus' 
data-content='<a href=\"https://google.fi/\" target=\"_blank\">Google</a>'>Google</a></p>";

?>
 
@Noz Ei toimi siksi kun tuota testaus2.php:n elementtiä ei ole sivulla siinä vaiheessa kun popper.js käynnistetään. Eli sinun pitää tuohon jqueryn loadiin lisätä complete callback, joka suorittaa uudestaan tuon
Koodi:
$('[data-toggle="popover"]').popover({html: true});
sen jälkeen kun tuo testaus2 on ladattu.
 
Minulla on djangolla ja bootstrap 4 toteutettu sivu jolla on table ja sen filteröintiin JS scripti.
Ongelmana on se että filtteröinti sotkee .table-striped harmaan ja valkoisen taustan järjestyksen.
Eli filteröityyn listaan saattaa jäädä kaksi harmaata tai valkoista saraketta peräkkäin, tai jopa pelkkiä valkoisia tai harmaita sarakkeita.
Millä ihmeellä tuon filteröinnin jälkeisen tablen värityksen saa päivittymään oikein?

Koodi:
Muokattu esimerkistä: https://www.w3schools.com/howto/howto_js_filter_table.asp

{% extends "base_generic.html" %}

{% block content %}
    <div class="d-flex">
        <div class="flex-fill">
            <br>
            <input class="form-control" onkeyup="myFunction()" id="myInput" type="text" placeholder="Etsi piirustusnumerolla.">
            <br>
            <table class="table table-condensed table-striped">
                <thead>
                <tr>
                    <th>Kappale</th>
                    <th>Piirustus numero</th>
                    <th>Varastossa</th>
                </tr>
                </thead>
                <tbody id="myTable">
                {% for workPiece in object_list %}
                    <tr>
                        <td><a href="{{ workPiece.get_absolute_update_url }}">{{ workPiece.name }}</td>
                        <td>{{ workPiece.drawingNumber }}</td>
                        <td>{{ workPiece.workPiecesInStock }}</td>
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
{% endblock %}

{% block script %}
    document.getElementById("btn3").className = "btn btn-primary w-100 active";

    function myFunction() {
    // Declare variables
        var input, filter, table, tr, td, i;
        input = document.getElementById("myInput");
        filter = input.value.toUpperCase();
        table = document.getElementById("myTable");
        tr = table.getElementsByTagName("tr");

    // Loop through all table rows, and hide those who don't match the search query
        for (i = 0; i < tr.length; i++) {
            td = tr[i].getElementsByTagName("td")[1];
            if (td) {
                if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
                    tr[i].style.display = "";
                } else {
                    tr[i].style.display = "none";
                }
            }
        }
    }
{% endblock %}
 
Minulla on djangolla ja bootstrap 4 toteutettu sivu jolla on table ja sen filteröintiin JS scripti.
Ongelmana on se että filtteröinti sotkee .table-striped harmaan ja valkoisen taustan järjestyksen.
Eli filteröityyn listaan saattaa jäädä kaksi harmaata tai valkoista saraketta peräkkäin, tai jopa pelkkiä valkoisia tai harmaita sarakkeita.
Millä ihmeellä tuon filteröinnin jälkeisen tablen värityksen saa päivittymään oikein?

Koodi:
Muokattu esimerkistä: https://www.w3schools.com/howto/howto_js_filter_table.asp

{% extends "base_generic.html" %}

{% block content %}
    <div class="d-flex">
        <div class="flex-fill">
            <br>
            <input class="form-control" onkeyup="myFunction()" id="myInput" type="text" placeholder="Etsi piirustusnumerolla.">
            <br>
            <table class="table table-condensed table-striped">
                <thead>
                <tr>
                    <th>Kappale</th>
                    <th>Piirustus numero</th>
                    <th>Varastossa</th>
                </tr>
                </thead>
                <tbody id="myTable">
                {% for workPiece in object_list %}
                    <tr>
                        <td><a href="{{ workPiece.get_absolute_update_url }}">{{ workPiece.name }}</td>
                        <td>{{ workPiece.drawingNumber }}</td>
                        <td>{{ workPiece.workPiecesInStock }}</td>
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
{% endblock %}

{% block script %}
    document.getElementById("btn3").className = "btn btn-primary w-100 active";

    function myFunction() {
    // Declare variables
        var input, filter, table, tr, td, i;
        input = document.getElementById("myInput");
        filter = input.value.toUpperCase();
        table = document.getElementById("myTable");
        tr = table.getElementsByTagName("tr");

    // Loop through all table rows, and hide those who don't match the search query
        for (i = 0; i < tr.length; i++) {
            td = tr[i].getElementsByTagName("td")[1];
            if (td) {
                if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
                    tr[i].style.display = "";
                } else {
                    tr[i].style.display = "none";
                }
            }
        }
    }
{% endblock %}

Ei taida ihan helposti onnistua, koska tuo scripti vain piilottaa noita elementtejä (näkyy hyvin selaimen lähdekoodia katsellessa), ja ilmeisesti se "joka toinen"-muotoilu on koodattu tuohon <tbody> tagiin (oisko CSS:n nth child). Eli ne piilotetut elementitkin muotoillaan, mutta niitä ei näytetä. Siksi tuo sekoaa. Helpointa on tietysti vaan luopua siitä striped muotoilusta.:p

En tiedä kuinka isoa listaa on tarkoitus tehdä, mutta itselle tuli idean tasolla mieleen, että tuon alkuperäisen listanhan voisi ehkä piilottaa silloin kun haetaan, ja scriptillä luodaan uusi <tbody> lista, johon sitten nuo luodaan nuo filtteröidyt rivit. Eli jos on jotain inputtia, niin renderöidään filtteröity uusi lista ja piilotetaan alkuperäinen, jos ei, niin näytetään koko alkuperäinen lista. Ei kyl varmaan ihan paras ratkaisu jos on todella suuri lista.
Tämä ratkaisu siis jos muotoiluun ei halua koskea. (tai luoda omaa)

Tällainen löytyi Googlesta, siellä muutamia vastauksia:
Reapply table striping after hiding rows (Twitter Bootstrap)

Nää oli kyl ihan hatusta.
Web-teknologioista kokemusta 2 viikkoa. :confused2:
 
@Dradge Siirrä piilotetut elementit taulukon loppuun? Ja jos elementillä on jokin id nii tämän ei pitäs vaikuttaa oikeen mihinkään.
 
Pikku kysymys liittyen SQL:lään.
Softassa on hakukenttä jolla haetaan datagridiin tietoa useammasta taulusta ja niiden tietyistä kolumneista.

private void tb_haku_TextChanged(object sender, EventArgs e)
{
DataTable dt = new DataTable();

dt.Columns.Add("Nimi");
dt.Columns.Add("Kuvaus");
dt.Columns.Add("Hinta");
dgtiedot.DataSource = dt;
dgtiedot.AutoGenerateColumns = false;

string pth = "Data Source=" + Application.StartupPath + "\\MokkiCE.sdf";
using (SqlCeConnection ce = new SqlCeConnection(pth))
{

string sql1 = $"SELECT * FROM R8_Palvelu where nimi like '%"+ tb_haku.Text+ "%'";


SqlCeDataAdapter da = new SqlCeDataAdapter(sql1, ce);
da.Fill(dt);
ce.Close();
dgtiedot.DataSource = dt;

}
}
Koodilla pystyy siis hakemaan tietoa "nimi" kolumnista, mutta ei muualta. Ongelma muodostuukin, kun tuolla pitäisi pystyä hakemaan useammasta kolumnista ja eri tauluista tietoa. Eli toisinsanoen tämä pätkä: $"SELECT * FROM R8_Palvelu where nimi like '%"+ tb_haku.Text+ "%'"; pitäisi saada sellaiseen muotoon, että sillä voi hakea useammasta kolumnista yhtä arvoa. Google on käännetty jo melko pitkälti ympäri eikä tuohon tunnu vastausta löytyvän.

Databasena toimii SQL compact ja koodikielenä C#.

Ideoita?
 
Nyt taitaa olla termit vähän hukassa, tai itse en ainakaan edes ymmärrä koko kysymystä. Select * kun hakee tiedot joka kolumnista. Ei mitään kuittailua, mutta en ihan ymmärrä mikä olisi haluttu lopputulos.
 
Nyt taitaa olla termit vähän hukassa, tai itse en ainakaan edes ymmärrä koko kysymystä. Select * kun hakee tiedot joka kolumnista. Ei mitään kuittailua, mutta en ihan ymmärrä mikä olisi haluttu lopputulos.
Tiedän kyllä. * on vain havainnollistamassa tuossa. Tuossa lauseessa siis voisi olla select nimi jne. ja se toimisi ihan samalla tavalla niinkin.
Sama kysymys?
how to search several columns in a sql query using concat and UPPER

CONCAT on varmaan se taikasana mitä kuitenkin nyt haet
Hyvin samantyyppinen tilanne. Tuo cocat ei ilmeisesti ole tuettuna SQL compactissa tai ainakin huusi jotain puuttuvaa osaa. Täytynee katsoa saako sitä jotenkin sovellettua.
 
Ei taida ihan helposti onnistua, koska tuo scripti vain piilottaa noita elementtejä (näkyy hyvin selaimen lähdekoodia katsellessa), ja ilmeisesti se "joka toinen"-muotoilu on koodattu tuohon <tbody> tagiin (oisko CSS:n nth child). Eli ne piilotetut elementitkin muotoillaan, mutta niitä ei näytetä. Siksi tuo sekoaa. Helpointa on tietysti vaan luopua siitä striped muotoilusta.:p

En tiedä kuinka isoa listaa on tarkoitus tehdä, mutta itselle tuli idean tasolla mieleen, että tuon alkuperäisen listanhan voisi ehkä piilottaa silloin kun haetaan, ja scriptillä luodaan uusi <tbody> lista, johon sitten nuo luodaan nuo filtteröidyt rivit. Eli jos on jotain inputtia, niin renderöidään filtteröity uusi lista ja piilotetaan alkuperäinen, jos ei, niin näytetään koko alkuperäinen lista. Ei kyl varmaan ihan paras ratkaisu jos on todella suuri lista.
Tämä ratkaisu siis jos muotoiluun ei halua koskea. (tai luoda omaa)

Tällainen löytyi Googlesta, siellä muutamia vastauksia:
Reapply table striping after hiding rows (Twitter Bootstrap)

Nää oli kyl ihan hatusta.
Web-teknologioista kokemusta 2 viikkoa. :confused2:

Tuon löysin itsekin googlella eikä tuo Anthonyn vastaus toiminut.
Koko lista ennen filteröintiä on vain 10-20 elementtiä pitkä joten eiköhän siinä ole mikä tahansa purkkaviritys tarpeeksi suorituskykyinen :rofl:
Itsellä taustalla vain pythonia ja HTML/CSS/Bootstrap alkeita, näköjään sitä joutuu JS / Jqueryä opettelemaan saadakseen sivun toimimaan :vihellys:

@Dradge Siirrä piilotetut elementit taulukon loppuun? Ja jos elementillä on jokin id nii tämän ei pitäs vaikuttaa oikeen mihinkään.

Elikkäs JS opiskelu alkakoon :tup: tällä hetkellä ei mitään käryä miten tuon ehdotuksesi toteuttaisi :btooth:

Kiitokset vastauksistanne :happy:
 
Tuon löysin itsekin googlella eikä tuo Anthonyn vastaus toiminut.
Koko lista ennen filteröintiä on vain 10-20 elementtiä pitkä joten eiköhän siinä ole mikä tahansa purkkaviritys tarpeeksi suorituskykyinen :rofl:
Itsellä taustalla vain pythonia ja HTML/CSS/Bootstrap alkeita, näköjään sitä joutuu JS / Jqueryä opettelemaan saadakseen sivun toimimaan :vihellys:



Elikkäs JS opiskelu alkakoon :tup: tällä hetkellä ei mitään käryä miten tuon ehdotuksesi toteuttaisi :btooth:

Kiitokset vastauksistanne :happy:

Koodi:
var row = document.getElementById('tableRowElement');
row.parentNode.appendChild(row);

tuosta pikku vinkki.
 
Pikku kysymys liittyen SQL:lään.
Softassa on hakukenttä jolla haetaan datagridiin tietoa useammasta taulusta ja niiden tietyistä kolumneista.

private void tb_haku_TextChanged(object sender, EventArgs e)
{
DataTable dt = new DataTable();

dt.Columns.Add("Nimi");
dt.Columns.Add("Kuvaus");
dt.Columns.Add("Hinta");
dgtiedot.DataSource = dt;
dgtiedot.AutoGenerateColumns = false;

string pth = "Data Source=" + Application.StartupPath + "\\MokkiCE.sdf";
using (SqlCeConnection ce = new SqlCeConnection(pth))
{

string sql1 = $"SELECT * FROM R8_Palvelu where nimi like '%"+ tb_haku.Text+ "%'";


SqlCeDataAdapter da = new SqlCeDataAdapter(sql1, ce);
da.Fill(dt);
ce.Close();
dgtiedot.DataSource = dt;

}
}
Koodilla pystyy siis hakemaan tietoa "nimi" kolumnista, mutta ei muualta. Ongelma muodostuukin, kun tuolla pitäisi pystyä hakemaan useammasta kolumnista ja eri tauluista tietoa. Eli toisinsanoen tämä pätkä: $"SELECT * FROM R8_Palvelu where nimi like '%"+ tb_haku.Text+ "%'"; pitäisi saada sellaiseen muotoon, että sillä voi hakea useammasta kolumnista yhtä arvoa. Google on käännetty jo melko pitkälti ympäri eikä tuohon tunnu vastausta löytyvän.

Databasena toimii SQL compact ja koodikielenä C#.

Ideoita?


Koodi:
SELECT column1, column2, ...
FROM table_name
WHERE nimi LIKE '%haku%'' OR kuvaus LIKE '%haku%'' OR hinta LIKE '%haku%'';

en mene takuuseen mitä tapahtuu mutta ehkä koittaisin tätä.
Koodi:
string sql1 = $"SELECT * FROM R8_Palvelu where nimi like '%"+ tb_haku.Text+ "%' or kuvaus like '%"+ tb_haku.Text+ "%' or hinta like '%"+ tb_haku.Text+ "%'";


ja useamman taulukon voit liittä mukaan UNION:illa.

Koodi:
SELECT id, 'messages' as 'table' FROM messages
WHERE content LIKE '%keyword%'
OR title LIKE '%keyword%'
UNION
SELECT id, 'topics' as 'table' FROM topics
WHERE content LIKE '%keyword%'
OR title LIKE '%keyword%'
UNION
SELECT id, 'comments' as 'table' FROM comments
WHERE content LIKE '%keyword%'
OR title LIKE '%keyword%'

Tämä ei sitten ole ehkä suotava tapa, jos dataa on joku isompi mälli!

EDIT
Katos vaan tää oliki SQL compact:ia. En ole varma löytyyko OR operaatiota, mutta ihmettelen jos ei löydy.
 
Viimeksi muokattu:
Koodi:
SELECT column1, column2, ...
FROM table_name
WHERE nimi LIKE '%haku%'' OR kuvaus LIKE '%haku%'' OR hinta LIKE '%haku%'';

en mene takuuseen mitä tapahtuu mutta ehkä koittaisin tätä.
Koodi:
string sql1 = $"SELECT * FROM R8_Palvelu where nimi like '%"+ tb_haku.Text+ "%' or kuvaus like '%"+ tb_haku.Text+ "%' or hinta like '%"+ tb_haku.Text+ "%'";


ja useamman taulukon voit liittä mukaan UNION:illa.

Koodi:
SELECT id, 'messages' as 'table' FROM messages
WHERE content LIKE '%keyword%'
OR title LIKE '%keyword%'
UNION
SELECT id, 'topics' as 'table' FROM topics
WHERE content LIKE '%keyword%'
OR title LIKE '%keyword%'
UNION
SELECT id, 'comments' as 'table' FROM comments
WHERE content LIKE '%keyword%'
OR title LIKE '%keyword%'

Tämä ei sitten ole ehkä suotava tapa, jos dataa on joku isompi mälli!

EDIT
Katos vaan tää oliki SQL compact:ia. En ole varma löytyyko OR operaatiota, mutta ihmettelen jos ei löydy.
Or löytyy kyllä, mutta valitti syntaksista eilen jotain. Tuota unionia täytyy kokeilla.

Edit: Union näyttäisi toimivan juuri kuten on haluttukin. Kiitokset. :tup:
 
Viimeksi muokattu:
Osaisiko joku jeesata tämän Python-ongelman kanssa:

Koodi:
        ls_comp = ls[:]
        for item in ls_comp:
            if len(item) > 3:
                item2 = item[:]
                item.append('00:00')
                item2.insert(3, '00:00')
                for ele, ele2 in zip(item[3:], item2[3:]):
                    t = time_operator(ele, ele2, '-')
                    s = int(t[:2]) * 60 * 60 + int(t[3:5]) * 60
                    if s < 180:
                        pass

ls on lista, joka pitää sisällään ison joukon listoja, joissa jokaisessa on 3-10 itemiä. Käytän tätä koodin pätkää vertaamaan listoissa olevia HH:MM-muotoisia kellonaikoja toisiinsa. Koodi ei ole valmis, koska tuosta lopussa olevasta if-lauseesta puuttuu vielä sisältö. Tarkoitus on poistaa listoista itemit, jotka ovat alle kolmen minuutin päästä toisistaan.

Koodi toimii tuohon if-lauseeseen asti hyvin, mutta jostain syystä "item.append('00:00')" joutuu myös ls-listaan. Ekalla rivillä otan ls-listasta kopion, mutta ja kaiken järjen mukaan tuon append-komennon pitäisi vaikuttaa vain siihen. Jostain syystä kuitenkin jos tulostan ls-listan tuon koodin jälkeen, niin jokaiseen listaan on ilmestynyt viimeiseksi itemiksi '00:00'.

Jaksaisiko joku jeesiä? :tdown:

Ne ls-listan sisältämät listat on suunnilleen tällaisia:
Koodi:
['0001603269', 'XX', '12', '07:50', '12:35', '13:20', '17:05']
['0001603269', 'XX', '13', '07:51', '12:34', '13:23', '17:04']
['0001603269', 'XX', '14', '07:53', '12:33', '13:23', '17:25']
['0001603269', 'XX', '15', '07:51', '12:33', '13:23', '17:05']
['0001603269', 'XX', '16', '07:47', '12:33', '13:23', '17:04']

Koodauskokemukseni on nyt pari kuukautta Pythonilla leikkimistä ilman mitään aiempaa kokemusta, joten jos koodi näyttää hirveältä, niin juuri nyt haluisin keskittyä enemmän tuon ongelman ratkaisuun.
 
Koodi toimii tuohon if-lauseeseen asti hyvin, mutta jostain syystä "item.append('00:00')" joutuu myös ls-listaan. Ekalla rivillä otan ls-listasta kopion, mutta ja kaiken järjen mukaan tuon append-komennon pitäisi vaikuttaa vain siihen. Jostain syystä kuitenkin jos tulostan ls-listan tuon koodin jälkeen, niin jokaiseen listaan on ilmestynyt viimeiseksi itemiksi '00:00'.

Arvatenkin slice-operaatio tuottaa ns. shallow copyn, eli listasta tehdään kopio mutta sisällön elementit osoittavat muistissa alkuperäisiin. Deep copyn tekeminen onnistunee ainakin copy-modulilla.
 
Arvatenkin slice-operaatio tuottaa ns. shallow copyn, eli listasta tehdään kopio mutta sisällön elementit osoittavat muistissa alkuperäisiin. Deep copyn tekeminen onnistunee ainakin copy-modulilla.
Kiitos. Tuolla deepcopylla lähti toimimaan. Täytyy näköjään olla varovaisempi kopioinnin kanssa. Olin jo koittanut näitä vaihtoehtoja:

  • ls_comp = list(ls)
  • ls_comp = ls[:]
mutta nuo kai sitten aina tekee sellaisen shallow copyn... Googlatessa tuli vastaan vain nuo vaihtoehdot ja olin ymmärtänyt, että ne nimen omaan luovat ihan erillisen listan.

Toimiva komento on siis:

  • ls_comp = copy.deepcopy(ls)
 
Kiitos. Tuolla deepcopylla lähti toimimaan. Täytyy näköjään olla varovaisempi kopioinnin kanssa. Olin jo koittanut näitä vaihtoehtoja:

  • ls_comp = list(ls)
  • ls_comp = ls[:]
mutta nuo kai sitten aina tekee sellaisen shallow copyn... Googlatessa tuli vastaan vain nuo vaihtoehdot ja olin ymmärtänyt, että ne nimen omaan luovat ihan erillisen listan.

Toimiva komento on siis:

  • ls_comp = copy.deepcopy(ls)
Nuo luovat erillisen listan, eli ls_comp:n muokkaaminen ei vaikuta ls:ään. Tämä ongelma syntyi siitä, että ls-listan jäsenet itsessään ovat listoja, joten ilman syväkopiointia ne kopioituivat viittauksina ja niiden muokkaaminen vaikutti tietysti alkuperäisen listan jäseniin.
 
Nuo luovat erillisen listan, eli ls_comp:n muokkaaminen ei vaikuta ls:ään. Tämä ongelma syntyi siitä, että ls-listan jäsenet itsessään ovat listoja, joten ilman syväkopiointia ne kopioituivat viittauksina ja niiden muokkaaminen vaikutti tietysti alkuperäisen listan jäseniin.
Juu no nyt kun sanoit tuon ääneen, niin yhtäkkiä tuntuu ihan itsestäänselvältä, että noin sen pitää mennä. :)
 

Statistiikka

Viestiketjut
253 896
Viestejä
4 412 730
Jäsenet
73 267
Uusin jäsen
Miketti

Hinta.fi

Back
Ylös Bottom