vibecoding

Tietokonejutut, pelit ja muu nörtismi; autot, kaasupullot ja muut lelut
Avatar
James Potkukelkka
Kitisijä
Viestit: 28644
Liittynyt: 23.01.2014 9:59

vibecoding

Viesti Kirjoittaja James Potkukelkka »

Opin viikonloppuna flunssassa uuden sanan ja kun su olo alkoi olla parempi, ryntäsin kokeilemaan

https://www.nytimes.com/2025/02/27/tech ... mming.html

Vibecodingissa henkilö, joka ei osaa koodata kuitenkin "koodaa" tekoälyn avulla. Tässä vaiheessa jo pyydän anteeksi palstan oikeilta koodaajilta. Kyseessä ei tietenkään ole oikea koodaus, vaan enemmän leikkiminen.

Itse latasin Cursorin https://www.cursor.com/en

Ensin tein "hello world" -tyylisenä yksinkertaisen to do listan. Sen jälkeen pong-kloonin.
Nothing dramatic happens at the tipping point. That just means Amoc is then doomed and it will slowly die, but that process could take 50 to 100 years.
Avatar
Bluntly
Kitisijä
Viestit: 24215
Liittynyt: 15.08.2005 8:41

Re: vibecoding

Viesti Kirjoittaja Bluntly »

Eipä ole pitkä matka low code paskaan.
"Vetäkää käteen, minä maksan" Bluntismi 2006.
Avatar
James Potkukelkka
Kitisijä
Viestit: 28644
Liittynyt: 23.01.2014 9:59

Re: vibecoding

Viesti Kirjoittaja James Potkukelkka »

Nyt on työn (tai leikin) alla kolmas ohjelma, josta voisi olla mulle itselleni jopa pientä hyötyä, jos se toimii luotettavasti.

Laskutan erästä päämiestä niin, että kerran kuussa ajan heidän potilastietojärjestelmästään pdf-raportin ja siirrän tekemäni työt siitä käsin excelliin, jossa lasken varsinaisen laskun. Ko. pdf on noin 15 sivuinen ja potilastietojärjestelmän kökköyden takia se sisältää suurimmaksi osaksi asiaan kuulumatonta tietoa. Varsinainen info on vaihteleva määrä (riippuen siitä, mitä olen tehnyt), yleensä noin 20 lukua, jotka muodostavat laskutusdatan.

Nyt yritän vibekoodata softan, joka osaisi poimia kyseisestä 15 sivuisesta pdf:stä ne oikeat numerot ja muodostaa niistä excelissä laskun.

Softan pitäisi siis osata etsiä ne oikeat 20 lukua ja sitten tehdä jokaiselle niistä oikeat temput (hinta vaihtelee, vuokra vaihtelee).

JOs saan toimimaan, niin todennäköisesti en kuitenkaan luota ko. ohjelmaan niin paljoa, että jättäisin homman pelkästään sen varaan :)

Mutta tämä on ajankulua.
Nothing dramatic happens at the tipping point. That just means Amoc is then doomed and it will slowly die, but that process could take 50 to 100 years.
sivustahuutaja
Kitisijä
Viestit: 23499
Liittynyt: 15.08.2005 0:29

Re: vibecoding

Viesti Kirjoittaja sivustahuutaja »

^ vaikken luottaisi kieli
mallien laskentaan, niin joku niistä voisi osata muodostaa taulukon haluamistasi luvuista.
Avatar
James Potkukelkka
Kitisijä
Viestit: 28644
Liittynyt: 23.01.2014 9:59

Re: vibecoding

Viesti Kirjoittaja James Potkukelkka »

Nuo tekoälypohjaiset koodausavustimet tuottavat aivan perinteistä koodia. Cursorin toiminta siis perustuu LLM-malleihin, mutta itse koodi on perinteistä.

Cursor aloitti lataamalla mun koneelle mm Microsoftin Visual Studion, erilaisia Python työkalua, javascript-työkalua jne. Se käyttelee sitten niitä. Tämän ohjelman se kirjoittaa pythonilla.

Selostin ongelman sille ja se päätteli, että helpoin toteuttaa python scriptillä. Javascript-työkaluja se latasi kun tein pong-kloonin, koska se arvioi, että kannattaa tehdä selaimessa ajettava ohjelma-
Nothing dramatic happens at the tipping point. That just means Amoc is then doomed and it will slowly die, but that process could take 50 to 100 years.
Avatar
aasi
Kitisijä
Viestit: 6752
Liittynyt: 01.07.2005 21:12
Paikkakunta: Uleåborg

Re: vibecoding

Viesti Kirjoittaja aasi »

PDF:t voi olla hankalia luettavia koneellisesti, ei välttämättä ole kovin rakenteisia.
Tasan ei mene muumit kanootissa.
Avatar
James Potkukelkka
Kitisijä
Viestit: 28644
Liittynyt: 23.01.2014 9:59

Re: vibecoding

Viesti Kirjoittaja James Potkukelkka »

^Joo. Olen nyt juuttunut ongelmaan, jossa skripti sekoaa rivinvaihdoista. Kun pdf tarkoitettu ihmisen luettavaksi, ei ole niin helppoa skriptille päätellä, mikä on samaa kokonaisuutta.

Samalla nyt tuli täyteen ilmaiskäytön raja. Ihmettelinkin, kuinka kauan saa ilmaiseksi jatkaa. 20dollaria /kk maksaisi jatkaa.
Nothing dramatic happens at the tipping point. That just means Amoc is then doomed and it will slowly die, but that process could take 50 to 100 years.
Avatar
James Potkukelkka
Kitisijä
Viestit: 28644
Liittynyt: 23.01.2014 9:59

Re: vibecoding

Viesti Kirjoittaja James Potkukelkka »

Tilasin 20 dollaria/kk paketin.
Nothing dramatic happens at the tipping point. That just means Amoc is then doomed and it will slowly die, but that process could take 50 to 100 years.
Avatar
James Potkukelkka
Kitisijä
Viestit: 28644
Liittynyt: 23.01.2014 9:59

Re: vibecoding

Viesti Kirjoittaja James Potkukelkka »

Nyt huomasin, että kyseinen raporttihan on mahdollista saada myös excell-muodossa :dumb: :facepalm:

Veikkaan, että python-scriptin paljon helpompi käsitellä exceliä kuin pdf:ää..
Nothing dramatic happens at the tipping point. That just means Amoc is then doomed and it will slowly die, but that process could take 50 to 100 years.
nokkaelain
Kitisijä
Viestit: 3115
Liittynyt: 10.03.2018 18:12

Re: vibecoding

Viesti Kirjoittaja nokkaelain »

James Potkukelkka kirjoitti: 05.03.2025 10:47 Nyt huomasin, että kyseinen raporttihan on mahdollista saada myös excell-muodossa :dumb: :facepalm:

Veikkaan, että python-scriptin paljon helpompi käsitellä exceliä kuin pdf:ää..
Excel:kin on aika perseestä. Juuri eilen avauduin Office-ohjelmiin liittyen (töissä pitäisi tehdä säännöllisesti henkilökohtainen roadmap PowerPoint-pohjalla.) En ole Officea käyttänyt pitään aikaan, mutta aikoinaan datan importaukseen LibreOffice oli parempi, lopuksi vaan lataus ja tallennus Excelillä, että on "yhteensopiva".
Avatar
Bluntly
Kitisijä
Viestit: 24215
Liittynyt: 15.08.2005 8:41

Re: vibecoding

Viesti Kirjoittaja Bluntly »

Jaahas. Joku pomo-osastolta oli onnistunut 'koodaaman' jotain AI:lla.

Kohta ne kuvittelee varmaan, että määrittelijät koodaa samantien.
"Vetäkää käteen, minä maksan" Bluntismi 2006.
Avatar
James Potkukelkka
Kitisijä
Viestit: 28644
Liittynyt: 23.01.2014 9:59

Re: vibecoding

Viesti Kirjoittaja James Potkukelkka »

Nyt se toimii

Koodi: Valitse kaikki

import pandas as pd
import re
from typing import List, Dict, Tuple
import os

class ServiceEntry:
    def __init__(self, code: str, description: str, hours: str, quantity: int, amount: float):
        self.code = code
        self.description = description
        self.hours = hours
        self.quantity = quantity
        self.amount = amount

    def to_dict(self) -> Dict:
        return {
            'Koodi': self.code,
            'Kuvaus': self.description,
            'Tunnit': self.hours,
            'Määrä': self.quantity,
            'Summa': self.amount
        }

def extract_doctor_section(df: pd.DataFrame) -> pd.DataFrame:
    """Extract the section for doctor with ID = 25."""
    # Find the row with ID = 25
    start_idx = df[df.iloc[:, 0].astype(str).str.contains('ID = 25', na=False)].index[0]
    
    # Find the next total row
    end_idx = df[df.iloc[:, 0].astype(str).str.contains('Kaikki Kela-luokat yhteensä', na=False)].index[0]
    
    # Extract the relevant section
    return df.iloc[start_idx:end_idx + 1]

def extract_service_lines(df: pd.DataFrame) -> Dict[str, List[ServiceEntry]]:
    # Initialize categories
    categories = {
        'Kela I': [],
        'Kela II': []
    }
    
    current_category = None
    
    print("\nProcessing Excel rows...")  # Debug print
    
    for idx, row in df.iterrows():
        # Get all columns as strings
        row_values = [str(val).strip() for val in row]
        row_str = ' '.join(row_values)
        
        # Skip empty rows
        if all(val == 'nan' for val in row_values):
            continue
            
        # Debug print for non-empty rows
        print(f"\nProcessing row {idx}: {row_values}")  # Debug print
            
        # Check for category headers
        if 'Kela luokka I' in row_str:
            current_category = 'Kela I'
            print(f"Found category: {current_category}")  # Debug print
            continue
        elif 'Kela luokka II' in row_str:
            current_category = 'Kela II'
            print(f"Found category: {current_category}")  # Debug print
            continue
        elif 'Kela luokka 0' in row_str:
            current_category = None
            print("Skipping Kela luokka 0")  # Debug print
            continue
        
        # Skip if no category is set or if it's a total line
        if not current_category or 'Yhteensä' in row_str or 'Kaikki Kela-luokat yhteensä' in row_str:
            continue
            
        # Look for a 6 or 7-digit code in column 2 (index 1)
        if len(row_values) > 1 and re.match(r'^\d{6,7}$', row_values[1]):
            code = row_values[1]
            description = row_values[2] if len(row_values) > 2 and row_values[2] != 'nan' else ""
            hours = row_values[3] if len(row_values) > 3 and row_values[3] != 'nan' else "0:00"
            qty = int(row_values[4]) if len(row_values) > 4 and row_values[4] != 'nan' else 0
            amount = float(row_values[5].replace(',', '.')) if len(row_values) > 5 and row_values[5] != 'nan' else 0.0
            
            print(f"Found entry - Code: {code}, Description: {description}, Time: {hours}, Qty: {qty}, Amount: {amount}")  # Debug print
            
            # Create the entry
            entry = ServiceEntry(
                code=code,
                description=description,
                hours=hours,
                quantity=qty,
                amount=amount
            )
            
            categories[current_category].append(entry)
            print(f"Added entry to {current_category}: {entry.code} - {entry.description}")  # Debug print
    
    # Print summary of found entries
    print("\nSummary of found entries:")
    for category, entries in categories.items():
        print(f"{category}: {len(entries)} entries")
        for entry in entries:
            print(f"  {entry.code}: {entry.description} - {entry.hours} {entry.quantity} {entry.amount}")
    
    return categories

def create_excel_report(categories: Dict[str, List[ServiceEntry]], output_file: str):
    try:
        # Create DataFrames for each category
        dfs = []
        
        for category_name, entries in categories.items():
            if entries:
                # Add category header
                header_df = pd.DataFrame([{'Koodi': f'=== {category_name} ==='}])
                dfs.append(header_df)
                
                # Convert entries to DataFrame
                df = pd.DataFrame([entry.to_dict() for entry in entries])
                dfs.append(df)
                
                # Calculate totals
                total_hours = sum(sum(map(int, entry.hours.split(':'))) / 60 for entry in entries)
                total_qty = sum(entry.quantity for entry in entries)
                total_amount = sum(entry.amount for entry in entries)
                
                # Add category totals
                total_df = pd.DataFrame([{
                    'Koodi': 'Yhteensä',
                    'Tunnit': f"{int(total_hours)}:{int((total_hours % 1) * 60):02d}",
                    'Määrä': total_qty,
                    'Summa': total_amount
                }])
                dfs.append(total_df)
                
                # Add empty row for separation
                dfs.append(pd.DataFrame([{'Koodi': ''}]))
        
        if not dfs:
            print("\nWarning: No entries found to create report")
            return
            
        # Combine all DataFrames
        final_df = pd.concat(dfs, ignore_index=True)
        
        # Save to Excel with proper engine
        with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
            # Write the DataFrame to Excel
            final_df.to_excel(writer, index=False, sheet_name='Palvelut')
            
            # Get the workbook and worksheet
            workbook = writer.book
            worksheet = workbook['Palvelut']
            
            # Adjust column widths
            worksheet.column_dimensions['A'].width = 15  # Code
            worksheet.column_dimensions['B'].width = 50  # Description
            worksheet.column_dimensions['C'].width = 10  # Hours
            worksheet.column_dimensions['D'].width = 10  # Quantity
            worksheet.column_dimensions['E'].width = 15  # Amount
            
            # Format numbers
            for row in worksheet.iter_rows(min_row=2):
                if row[4].value and isinstance(row[4].value, (int, float)):  # Amount column
                    row[4].number_format = '#,##0.00'
            
            # Save the workbook
            workbook.save(output_file)
            
    except Exception as e:
        print(f"\nVirhe Excel-tiedoston luomisessa: {str(e)}")
        raise

def process_excel(excel_path: str, output_path: str):
    """Process Excel file and create report."""
    try:
        # Remove quotes if present
        excel_path = excel_path.strip('"').strip("'")
        
        print(f"\nReading Excel file: {excel_path}")  # Debug print
        
        # Read Excel file - use all columns
        df = pd.read_excel(excel_path, header=None)
        print(f"Found {len(df)} rows in Excel file")  # Debug print
        
        # Find the doctor's section
        doctor_start = None
        doctor_end = None
        
        for idx, row in df.iterrows():
            row_str = ' '.join(str(val) for val in row)
            if 'ID = 25' in row_str:
                doctor_start = idx
            elif doctor_start is not None and 'FF' in row_str:
                doctor_end = idx
                break
        
        if doctor_start is None:
            print("Error: Could not find doctor with ID = 25")
            return
            
        print(f"Found doctor section: rows {doctor_start} to {doctor_end}")  # Debug print
        
        # Extract only the doctor's section
        df = df.iloc[doctor_start:doctor_end]
        
        # Extract service lines
        categories = extract_service_lines(df)
        
        # Create Excel report
        create_excel_report(categories, output_path)
        
        print(f"\nRaportti luotu onnistuneesti: {output_path}")
        print("\nKäsitellyt kategoriat:")
        for category, entries in categories.items():
            if entries:
                total_hours = sum(sum(map(int, entry.hours.split(':'))) / 60 for entry in entries)
                total_amount = sum(entry.amount for entry in entries)
                print(f"{category}: {len(entries)} riviä, {int(total_hours)}:{int((total_hours % 1) * 60):02d} tuntia, yhteensä {total_amount:.2f}€")
            else:
                print(f"{category}: 0 riviä")
        
    except FileNotFoundError:
        print(f"\nVirhe: Excel-tiedostoa ei löydy polusta: {excel_path}")
        print("Varmista, että polku on oikein ja tiedosto on olemassa.")
    except Exception as e:
        print(f"\nVirhe Excel-tiedoston käsittelyssä: {str(e)}")
        print("Jos ongelma jatkuu, varmista että Excel-tiedosto ei ole vaurioitunut.")

def main():
    print("\nExcel Palveluraportin Käsittelijä")
    print("==================================")
    print("\nTämä ohjelma lukee Excel-raportin ja luo uuden Excel-tiedoston palveluista.")
    print("(Käsittelee vain lääkärin ID = 25 tiedot)")
    
    # Get Excel path
    print("\nAnna Excel-tiedoston polku:")
    print("(Voit kopioida polun Resurssienhallinnasta ja liittää sen tähän)")
    excel_path = input("> ").strip()
    
    if not excel_path:
        print("\nVirhe: Excel-tiedoston polku on pakollinen!")
        return
    
    # Get output path
    print("\nAnna Excel-tiedoston tallennuspolku")
    print("(Paina Enter käyttääksesi oletusta 'report.xlsx')")
    output_path = input("> ").strip()
    
    if not output_path:
        output_path = "report.xlsx"
    
    # Remove quotes if present
    excel_path = excel_path.strip('"').strip("'")
    output_path = output_path.strip('"').strip("'")
    
    # Ensure Excel exists
    if not os.path.exists(excel_path):
        print(f"\nVirhe: Excel-tiedostoa ei löydy polusta: {excel_path}")
        print("Varmista, että polku on oikein ja tiedosto on olemassa.")
        return
    
    # Process the Excel
    process_excel(excel_path, output_path)

if __name__ == "__main__":
    main() 
Nothing dramatic happens at the tipping point. That just means Amoc is then doomed and it will slowly die, but that process could take 50 to 100 years.
Avatar
James Potkukelkka
Kitisijä
Viestit: 28644
Liittynyt: 23.01.2014 9:59

Re: vibecoding

Viesti Kirjoittaja James Potkukelkka »

Nyt saatu luvut ulos. Nyt tarvitaan enää kerto- ja vähennyslaskua. Olisin säästänyt muutaman tunnin, jos olisin heti tajunnut, että raportin potilastietojärjestelmästä saa ulos myös excelinä.
Nothing dramatic happens at the tipping point. That just means Amoc is then doomed and it will slowly die, but that process could take 50 to 100 years.