Programming

26206 readers
338 users here now

Welcome to the main community in programming.dev! Feel free to post anything relating to programming here!

Cross posting is strongly encouraged in the instance. If you feel your post or another person's post makes sense in another community cross post into it.

Hope you enjoy the instance!

Rules

Rules

  • Follow the programming.dev instance rules
  • Keep content related to programming in some way
  • If you're posting long videos try to add in some form of tldr for those who don't want to watch videos

Wormhole

Follow the wormhole through a path of communities !webdev@programming.dev



founded 2 years ago
MODERATORS
1
 
 

Hi all, I'm relatively new to this instance but reading through the instance docs I found:

Donations are currently made using snowe’s github sponsors page. If you get another place to donate that is not this it is fake and should be reported to us.

Going to the sponsor page we see the following goal:

@snowe2010's goal is to earn $200 per month

pay for our 📫 SendGrid Account: $20 a month 💻 Vultr VPS for prod and beta sites: Prod is $115-130 a month, beta is $6-10 a month 👩🏼 Paying our admins and devops any amount ◀️ Upgrade tailscale membership: $6-? dollars a month (depends on number of users) Add in better server infrastructure including paid account for Pulsetic and Graphana. Add in better server backups, and be able to expand the team so that it's not so small.

Currently only 30% of the goal to break-even is being met. Please consider setting up a sponsorship, even if it just $1. Decentralized platforms are great but they still have real costs behind the scenes.

Note: I'm not affiliated with the admin team, just sharing something I noticed.

2
 
 

The other day at work I stumbled upon this bug and thought it was worth to write a blog post about. Spoiler: It has nothing to do with timezones!

TLDR: According to ISO standard 8601 (which is what Python's date.isocalendar().week uses for example), the first week of the year is the week with the first Thursday of the year. So sometimes the first few days of January belong to the last week of previous year, and sometimes the last few days of December belong to the first week of next year :D

3
4
 
 

Hello,

I am thinking about teaching my students JavaScript first so that they can start creating websites and make their career, what are your thoughts?

5
 
 

What I like about this text is a focus on what are positive goals, what is desired, and what is desirable.

Instead of a negative focus on what we don't want. I think focusing on something positive is a far better strategy.

6
27
Martin Fowler: ORM Hate (martinfowler.com)
submitted 1 day ago* (last edited 1 day ago) by HaraldvonBlauzahn@feddit.org to c/programming@programming.dev
 
 

This is a pragmatic piece of Fowler on the rather dry topic of Object-relational mappings - in short, the attempt to marry an object-oriented code base with a relational data base.

Usually you'd get enough early success to commit deeply to the framework and only after a while did you realize you were in a quagmire - this is where I sympathize greatly with Ted Neward's famous quote that object-relational mapping is the Vietnam of Computer Science

What Fowler refers to here, is Ted Neward's article "The Vietnam Of Computer Science"

7
 
 

Code review answers: “Should this be part of my product?”

That’s a judgement call, and it’s a fundamentally different question than “does it work.” Does this approach fit our architecture? Does it introduce complexity we’ll regret in six months? Are we building toward the product we intend, or accumulating decisions that pull us sideways?

8
9
10
11
 
 

As the title says, it's a rather simple golang script for creating memories in Immich based on certain criteria, since there aren't any customization options in the official app.

As you may gather from the README, I created this for very personal reasons. But I wanted to share it here in case someone else finds it useful as well.

Currently it can do filtering based on people, and tags. But I'm more than happy to add more options, if requested.

12
 
 

update!

The program now uses argparse (as suggested by somebody) and accepts the arguments gyear, gmonth, and gday. I think it works pretty well! I have also implemented a --year tag (or -y for short) that creates a printout of the Symmetry454 calendar year. Additionally, much of the information that isn't very useful, like the number of weeks in a year, will now be hidden if you don't use the --verbose tag (or -v for short). The year preview also adds the leap week to December if needed.

original post:

If you didn't know, Symmetry454 is a proposal for the reform of the Gregorian calendar made in 2002 that, as the name implies, has months that alternate between four and five weeks. It is perennial, meaning weekdays of dates don't change (so you can reuse calendars as long as it's not a leap year!) and certain holidays that depend on the nth weekday would have fixed dates (like Easter is proposed to be on the 7th of April). It interestingly has a leap week system that alternates between 5 and 6 year gaps between leap years, with an additional week being added to December during leap years. Personally, I find a leap week far more fun than a leap day.

I have made a small Python script that converts Gregorian dates into Symmetry454 dates, which follows the steps noted by the person who made Symmetry454 (they had a whole PDF and everything explaining each step to calculate all that, super helpful!). Currently, it accepts Gregorian dates (year, month, and day) and returns the Symmetry454 date (in YYYY-MM-DD format), as well as some additional information (like a basic calendar that shows the position of the day in the month. There is also a function for outputting a year, what quarter the day is in, and the fixed date since a defined epoch)

It doesn't really do much at the moment, but in the future, I would like the program to be able to let the user explore the calendar of different Symmetry454 years, as well as easily interconvert the dates of the two systems. There are probably a bunch of bugs in my code, and it's not really all that practical, but making it has been pretty fun!

If you want to check it out, it's on Codeberg with the GPLv3 license: https://codeberg.org/sbird/py-symmetry454

The PDF found in this website detailing the calculations for converting from Gregorian to Symmetry454 was very helpful, here it is for reference: https://kalendis.free.nf/symmetry.htm (go all the way down to "Documentation", it's the PDF labelled "calendar arithmetic")

No AI was used to create this project, all mistakes and bugginess are my own.

13
14
 
 

This is a follow up to my previous post here - https://programming.dev/post/46041021 - For those that want a tldr: I'm making a php site for myself writing nearly everything by hand. The only external library I'm using is Parsedown.

After a good time working on my site, I'm happy to announce that I've officially shared it with my friends^[I won't share it here as the site is tied to a different online persona of mine]! The site isn't really "ready" yet, but it's very usable and readable, so that's good!

As for code quality? Well... It's kinda awful. Instead of this:

class User {
  $login = new String();
  $email = new String();
  ...
}

I'm using named arrays (hashes)^[Kinda funny how associative arrays have soe many different names in other languages: hash, dictionary, map] everywhere:

class User {
  $columns = array( 'login' => '',
  'email' => '',
  ...
}

"But WHY???", you might be asking. Well, to facilitate the creation of the database from zero! Here's an example of my trick:

abstract class Common {
 /**
  a bunch of different, generic select and update functions
*/
}
class Users extends Common{
$cols = array('uid'=> 'primary key auto_increment',
    'vc1_login'=> 'unique not null',
    'vc1_display_name'=> '',
    'vc2_password'=> 'not null',
    'dat_created_at'=> 'not null',
    'bol_enabled'=> 'default 1',
    ...
}

With this, the $key part of the hash doubles as the column name and their default/new values are always the details needed for the creation of their respective columns. I also treat the ::class as part of the table name. With a few functions, I can easily recreate the database from zero, something which I've tested a few times now and can confirm that it works great! Also, with key pairs, making generic SQL functions becomes very easy with foreach() loops of the $cols hash. Example:

abstract class Common {
public function selectColumns($columns, $table = '', $where='1', $orderby = '') {
        $conn = connectDb(); //static function outside class
        if ($table == '') {$table = $this::class;}
        $coll = '';
        foreach ($columns as $cols) {
            $coll .= $cols.', ';
        }
        $coll = substr($coll,0,-2);
        $stmt = $conn->prepare("SELECT ".$coll." FROM `T_".$table."` WHERE ".$where." ".$orderby.";");
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC); 
//Fetch_Assoc is used so I'm forced to always use the $key in the returned array
    }

// This function will attempt to update all non-empty pairs of a given object
public function updateColsUid(){
        $conn = conectaBanco();
        $sql = "UPDATE `T_".$this::class."` SET ";
        $keys = array('uid' => $this->cols['uid']);
        foreach ($this->cols as $key => $value) {
            if (($value != '') and ($key != 'uid')) {
                $sql .= " `". $key. "` = :" . $key . " ,";
                $keys[$key] = $value;
            }
        }
        $sql = substr($sql,0,-1);
        $sql .= " WHERE `uid` = :uid;";
        $stmt = $conn->prepare($sql);
        $stmt->execute($keys);
        return $stmt->rowCount();
    }

The biggest problem with this is that if I ever remove, add or rename any of these $keys, it'll be a fucking chore to update code that references it. I'll look into using proper variables for each column in the future, especially as a database creation is something you usually only do once. On the plus side, this is the most portable php site I've ever did (1 out of 1, but whatever)

Anyway, current functionality includes creating an account, modifying some aspects^[I want to note that there was a bunch of validation that I initially didn't think of doing, but luckily had a couple of "Wait, what if..." moments. One of those was to properly escape a user's username and display name, otherwise, when echo'ing it, <b>Bob</b> would show as Bob. While the fields probably wouldn't be enough to fit anything malicious (fitting something malicious inside a varchar100 would be a real feat, ngl), it's better to close this potential hole.] of it (profile description, display name (which is html escaped, so no funny business here), signature), logging in, letting the admin make new posts, letting anyone logged in comment on existing posts, comment moderation.

I also keep track of every page visitors are going to, saving these to the database (user agent, IP, page visited) - this will be the table that will fill up faster than any other, but might also allow me to catch eventual bots that ignore robots.txt - supposing I can figure them out.

Initially, I was planning on having each post select from a list of existing categories (category N -> N posts), but after some thought, decided against that and came up with a working alternative. Posts now have a single column where categories are manually written in, separated by commas. I later retrieve them with select distinct, explode() the string into an array and finally remove duplicates with array_unique(), making it easy for visitors, and for me, to get all the unique and valid categories.

One thing I'm doing that I'm not sure whether it's good, neutral or bad design/architecture, is using the same site that has the form to also validate/insert data, as in: instead of having newpost.php and validate_and_insert_post.php files doing separate jobs, my newpost.php is the page has the form and also receives the form in order to validate and insert into the database.

The whole thing's currently sitting at 220kb, unzipped, counting the leftover files that I'm no longer using. The fact that I can deploy this literally anywhere with a working php 8+ server without typing any terminal commands makes me very happy.

15
16
24
submitted 4 days ago* (last edited 4 days ago) by mattreb@feddit.it to c/programming@programming.dev
 
 

Hey, I want your opinion on code reviews, what is the best way to use them in a professional environment? Pick one of the following and give me your thoughts (from the most forgiving to the most strict):

  1. no code reviews, they are useless
  2. optional code reviews
  3. mandatory reviews on code that is already merged, optional fixes
  4. mandatory reviews on code before merging (like a pull request), with a time-frame for optional fixes (i.e. whether to fix what has been pointed out is up to the author), merge will occur anyway.
  5. mandatory reviews on code before merging (PR) with mandatory fixes.

Of course in open source development with public contributions, you'll often see (5), but I'm not convinced it could work in professional dev.

Edit: I'm talking about a team of 5 mid to senior devs (no junior or interns) working on a 2-3 year project without many security concerns, but feel free to give me your general opinion.

17
18
 
 

Today, AI is rapidly changing the way we build software, and the pace of that change is only accelerating. If our goal is to make programming more productive, then building at the frontier of AI and software feels like the highest-leverage thing we can do.

It is increasingly clear to me that Codex is that frontier. And by bringing Astral’s tooling and expertise to OpenAI, we’re putting ourselves in a position to push it forward. After joining the Codex team, we’ll continue building our open source tools, explore ways they can work more seamlessly with Codex, and expand our reach to think more broadly about the future of software development.

19
 
 

Not sure if it’s just me, but I’ve been running into this quite a bit.

My client conversations are spread across different messaging platforms, and sometimes important or more detailed discussions just get buried or overlooked.

It’s not even about the number of messages, it’s the fragmentation that makes it hard to keep track of everything in one flow.

Anyone else dealing with this? How are you keeping track of conversations without things slipping through?

20
 
 
21
 
 

Hello programming!

I've recently wanted to create a blog with Gemini, but I have a very strong disdain for writing boilerplate. It's a scar that has never left me since HTML. Instead, I JUST wanted to write the content, and not have to worry much about writing the same layout (though it matters less than in HTML).

Therefore, I created gtm with the knowledge that no one else tried doing the same thing I was doing. I ended up proving myself wrong after discovering Michael Lazar's Jetforce, which is currently a much more complete project than my own. However, I still believe that working on it would result in something interesting.

Feel free to let me know if you want anything added to this. Currently, Lua is something I really want to add to gtm since I want people to be able to write their own functionality. I'd be glad to see what you lot have to say.

A side note before anyone gets curious, I wrote this entirely by hand as my first major project, and is also being used for me to learn Rust. No LLMs, GPTs, AI-powered smart fridges or similar were involved.

Cheers!

22
 
 

Hello everyone 👋, I’m seeking advice from experienced devs. I understand the fundamentals of Python (I've got them down pat). The challenge is that when I actually work on real-world projects, even though I know how the project should be built (theoretically), I have trouble executing it.

I understand the thought process behind the project and can identify what I need to do, but when I am faced with a specific task, I tend to forget the actual implementation of the task.

I'm trying to transition into AI/ML; however, I'm struggling with the above issues.

Can anyone give me:

  • Suggestions on how to become better at practical thinking while coding?
  • Suggestions on how to effectively use learned concepts in real-world projects?
  • Suggestions on how to increase my problem-solving skills?
  • Recommendations for some sort of practice project or project-based learning?

Any support, thoughts, guidance or past experiences you can share would be a great help and Share Some Material For Learning.

Thank you.

23
24
6
Whatup programmers (programming.dev)
submitted 6 days ago* (last edited 6 days ago) by comradelux@programming.dev to c/programming@programming.dev
 
 

To anyone reading, im leaving. The moderation on this place sucks.

I cant tell someone to add authentication to their app I cant tell anyone to self reflect

But people are allowed to bully others out of learning? yeah bye

25
 
 

JADEx (Java Advanced Development Extension) is a practical Java safety layer that enhances the safety of your code by providing null-safety and readonly(final-by-default) enforcement. It strengthens Java’s type system without requiring a full rewrite, while fully leveraging existing Java libraries and tools.

As of v0.59, JADEx now ships a Gradle plugin alongside the existing IntelliJ plugin.


What JADEx does

JADEx extends Java at the source level with two core safety mechanisms:

Null-Safety

  • Type → non-nullable by default
  • Type? → nullable
  • ?. → null-safe access operator
  • ?: → Elvis operator (fallback value)
String? name = repository.findName(id);
String upper = name?.toLowerCase() ?: "UNKNOWN";

Compiles to standard Java:

@Nullable String name = repository.findName(id);
String upper = SafeAccess.ofNullable(name).map(t0 -> t0.toLowerCase()).orElseGet(() -> "UNKNOWN");

Readonly (Final-by-Default)

  • A single apply readonly; directive makes fields, local variables, and parameters final by default
  • Explicit mutable modifier for intentional mutability
  • Violations reported as standard Java compile-time errors

What's new in v0.59 - Gradle Plugin

The JADEx Gradle plugin (io.github.nieuwmijnleven.jadex) integrates .jadex compilation into the standard Gradle build lifecycle via a compileJadex task.

plugins {
    id 'io.github.nieuwmijnleven.jadex' version '0.59'
}
  • Default source directory: src/main/jadex
  • Default output directory: build/generated/sources/jadex/main/java
  • Optional jadex {} DSL block for custom configuration
  • IntelliJ plugin now integrates with the Gradle plugin via the Gradle Tooling API for consistent path resolution between IDE and build pipeline
jadex {
    sourceDir = "src/main/jadex"
    outputDir = "build/generated/sources/jadex/main/java"
}

Other Improvements

  • IntelliJ Plugin - Gradle Plugin Integration

    • The IntelliJ plugin now integrates with the JADEx Gradle plugin via the Gradle Tooling API.
    • Source and output directory resolution is now delegated to the Gradle plugin configuration, ensuring consistency between the IDE and the build pipeline.
  • Parser Performance Optimization

    • Improved parser speed by optimizing parser rules.
    • Reduces analysis latency in the IDE, providing a smoother editing experience for large .jadex files.

Design philosophy

JADEx is not a new language. It does not modify the JVM. It operates purely at the source level and generates standard Java code, meaning it is fully compatible with existing Java libraries, tools, and workflows. The goal is to make null-safety and readonly(final-by-default) enforcement practical and incremental, applicable file by file to existing codebases without a full rewrite.


Links

Feedback and questions welcome.

view more: next ›