[syndicated profile] the_daily_wtf_feed

Posted by Remy Porter

Carlos and Claire found themselves supporting a 3rd party logistics package, called IniFreight. Like most "enterprise" software, it was expensive, unreliable, and incredibly complicated. It had also been owned by four different companies during the time Carlos had supported it, as its various owners underwent a series of acquisitions. It kept them busy, which is better than being bored.

One day, Claire asked Carlos, "In SQL, what does an exclamation point mean?"

"Like, as a negation? I don't think most SQL dialects support that."

"No, like-" and Claire showed him the query.

select * from valuation where origin_country < '!'

"IniFreight, I presume?" Carlos asked.

"Yeah. I assume this means, 'where origin country isn't blank?' But why not just check for NOT NULL?"

The why was easy to answer: origin_country had a constraint which prohibited nulls. But the input field didn't do a trim, so the field did allow whitespace only strings. The ! is the first printable, non-whitespace character in ASCII (which is what their database was using, because it was built before "support wide character sets" was a common desire).

Unfortunately, this means that my micronation, which is simply spelled with the ASCII character 0x07 will never show up in their database. You might not think you're familiar with my country, but trust me- it'll ring a bell.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
[syndicated profile] raspberry_pi_feed

Posted by Sophie Ashford

We love hearing from members of the community and sharing the stories of amazing young people, volunteers, and educators who are using their passion for technology to create positive change in the world around them.

Growing up in Mathare, one of Nairobi’s largest informal settlements, Douglas experienced first-hand what it meant to go without access to education and opportunity. His experience sparked a Code Club journey that is already hugely inspiring… and it’s only just getting started.

Douglas (second from left) with members of the Raspberry Pi Foundation team
Douglas (second from left) with members of the Raspberry Pi Foundation team

Driven by a desire to help 

For Douglas and many of his peers, the limited access to education in Mathare often meant being left with no clear path to earn a livelihood. Douglas saw opportunity in technology — he wanted to increase access in this field for the young people in Mathare and raise their ambitions.

“Why are we doing technology? Because we believe that tech does not have a boundary. As long as you have access to the internet and you can learn some basic skills… the opportunities are limitless.”

That belief became the keystone of Oasis Mathare, an organisation co-founded by Douglas and a group of others with similar lived experiences. Like Douglas, most of the founding members haven’t followed a standard path with formal schooling, but all understand the power of technology to transform lives.

From Photoshop to programming

Douglas’ own tech journey began humbly, and was sparked by his curiosity.

“After primary, I didn’t go straight to high school. I spent two years working in a nearby barber shop. Then I think I just fell in love with computers. I learned how to do some basic stuff with design and used to play around with Photoshop.”

From there, he taught himself web design and programming skills, which began to open new doors. Eventually, he went back to university to study business and information technology to deepen his knowledge, but even before that, Douglas had already started giving back.

“We used to hold a club providing a space for kids to come and play games on computers. That sort of grew from just Saturdays to a few times a week… and now it’s full time.”

One of Oasis Mathare’s Code Clubs in action
One of Oasis Mathare’s Code Clubs in action

Why Code Clubs?

Today, Oasis Mathare runs intensive software engineering and robotics programs that last between 9 and 12 months. But back in the early days of the organisation, Douglas quickly realised that many young people were struggling to keep up — not because of ability, but because they’d never used a computer before.

“So, we started Code Clubs to introduce these principles of programming at an early age… and we actually realised that those who have gone through Code Club take less time to complete our software engineering and robotics classes.”

Code Clubs now serve as a stepping stone at Oasis Mathare. They help introduce computer literacy and programming concepts to young people early, making it easier for them to thrive in more advanced programs.

The power of role models

The impact of the program is already visible. Many graduates of Oasis Mathare programs go on to volunteer and eventually teach, serving as role models for the younger learners.

“Oasis Mathare has 6 full-time staff. There are 12 Code Club leaders. They are our graduates from the software engineering program. We are plugging them into the Code Clubs to help them gain confidence and help the next generation.”

The Code Clubs are held both in schools and at the Oasis Mathare centre, creating safe, structured environments for learning, experimenting, and collaborating.

Douglas supporting a Code Club mentor
Douglas supporting a Code Club mentor

Building with what they have

Before setting up Code Clubs, Oasis Mathare ran STEM clubs that used a variety of resources, but the cost and maintenance became a barrier. When they discovered Code Club’s free-to-access resources, everything changed.

“We found [the resources] very useful. The good thing about Code Club is you can plan sessions using resources that are freely available, like Scratch. It’s really straightforward.”

The biggest challenge now? Internet access is limited, so Douglas and his team often work offline. The team have started using the Raspberry Pi Foundation’s offline resources, and look forward to more being available in the future.

What’s next for Douglas and Oasis Mathare?

Douglas and the Oasis Mathare team have already achieved so much. This was recognised with a royal seal of approval in 2018, when Douglas was honoured with the Queen’s Young Leaders Award by Queen Elizabeth at Buckingham Palace. Through the award, he gained access to world-class mentoring and leadership training from the University of Cambridge, helping him to amplify his impact back home.

So, what’s next? Douglas’ vision for the future is bold and clear.

“The main idea is to ensure that all kids in Mathare know at least one computer language. Not for the sake of it, but to use the principles of programming to solve their local problems.”

By learning coding, young people build more than just technical skills. They learn to think critically, work in teams, and solve problems in their communities. For Douglas, that’s the real impact.

“The overall goal is to ensure that no youth in Mathare are left behind and they all have the opportunity to develop essential skills from an early age.”

Students at an Oasis Mathare Code Club working together

Looking further ahead

Oasis Mathare runs Code Clubs weekly, all year round, and Douglas is always looking for ways to expand the program’s reach, especially through partnerships, sponsorships, and sharing their successes so far.

With more resources, more local leaders, and a whole community behind him, Douglas is rewriting the narrative for young people in Mathare. You can find out more about Oasis Mathare on their official website.

If you’d like to support young people in your community to explore coding, why not start a Code Club? The team will support you every step of the way with resources, training, and a collaborative community. Find out more on the Code Club website.

The post Giving back through Code Club: Meet Douglas appeared first on Raspberry Pi Foundation.

CodeSOD: Born Single

Jul. 15th, 2025 06:30 am
[syndicated profile] the_daily_wtf_feed

Posted by Remy Porter

Alistair sends us a pretty big blob of code, but it's a blob which touches upon everyone's favorite design pattern: the singleton. It's a lot of Java code, so we're going to take this as chunks. Let's start with the two methods responsible for constructing the object.

The purpose of this code is to parse an XML file, and construct a mapping from a "name" field in the XML to a "batch descriptor".

	/**
	 * Instantiates a new batch manager.
	 */
	private BatchManager() {
		try {
			final XMLReader xmlReader = XMLReaderFactory.createXMLReader();
			xmlReader.setContentHandler(this);
			xmlReader.parse(new InputSource(this.getClass().getClassLoader().getResourceAsStream("templates/" + DOCUMENT)));
		} catch (final Exception e) {
			logger.error("Error parsing Batch XML.", e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see nz.this.is.absolute.crap.sax.XMLEntity#initChild(java.lang.String,
	 * java.lang.String, java.lang.String, org.xml.sax.Attributes)
	 */
	@Override
	protected ContentHandler initChild(String uri, String localName,
			String qName, Attributes attributes) throws SAXException {
		final BatchDescriptor batchDescriptor = new BatchDescriptor();
		// put it in the map
		batchMap.put(attributes.getValue("name"), batchDescriptor);
		return batchDescriptor;
	}

Here we see a private constructor, which is reasonable for a singleton. It creates a SAX based reader. SAX is event driven- instead of loading the whole document into a DOM, it emits an event as it encounters each new key element in the XML document. It's cumbersome to use, but far more memory efficient, and I'd hardly say this.is.absolute.crap, but whatever.

This code is perfectly reasonable. But do you know what's unreasonable? There's a lot more code, and these are the only things not marked as static. So let's keep going.

	// singleton instance so that static batch map can be initialised using
	// xml
	/** The Constant singleton. */
	@SuppressWarnings("unused")
	private static final Object singleton = new BatchManager();

Wait… why is the singleton object throwing warnings about being unused? And wait a second, what is that comment saying, "so the static batch map can be initalalised"? I saw a batchMap up in the initChild method above, but it can't be…

	private static Map<String, BatchDescriptor> batchMap = new HashMap<String, BatchDescriptor>();

Oh. Oh no.

	/**
	 * Gets the.
	 * 
	 * @param batchName
	 *            the batch name
	 * 
	 * @return the batch descriptor
	 */
	public static BatchDescriptor get(String batchName) {
		return batchMap.get(batchName);
	}

	/**
	 * Gets the post to selector name.
	 * 
	 * @param batchName
	 *            the batch name
	 * 
	 * @return the post to selector name
	 */
	public static String getPostToSelectorName(String batchName) {
		final BatchDescriptor batchDescriptor = batchMap.get(batchName);
		if (batchDescriptor == null) {
			return null;
		}
		return batchDescriptor.getPostTo();
	}

There are more methods, and I'll share the whole code at the end, but this gives us a taste. Here's what this code is actually doing.

It creates a static Map. static, in this context, means that this instance is shared across all instances of BatchManager.They also create a static instance of BatchManager inside of itself. The constructor of that instance then executes, populating that static Map. Now, when anyone invokes BatchManager.get it will use that static Map to resolve that.

This certainly works, and it offers a certain degree of cleanness in its implementation. A more conventional singleton would have the Map being owned by an instance, and it's just using the singleton convention to ensure there's only a single instance. This version's calling convention is certainly nicer than doing something like BatchManager.getInstance().get(…), but there's just something unholy about this that sticks into me.

I can't say for certain if it's because I just hate Singletons, or if it's this specific abuse of constructors and static members.

This is certainly one of the cases of misusing a singleton- it does not represent something there can be only one of, it's ensuring that an expensive computation is only allowed to be done once. There are better ways to handle that lifecycle. This approach also forces that expensive operation to happen at application startup, instead of being something flexible that can be evaluated lazily. It's not wrong to do this eagerly, but building something that can only do it eagerly is a mistake.

In any case, the full code submission follows:

package nz.this.is.absolute.crap.server.template;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;

import nz.this.is.absolute.crap.KupengaException;
import nz.this.is.absolute.crap.SafeComparator;
import nz.this.is.absolute.crap.sax.XMLEntity;
import nz.this.is.absolute.crap.selector.Selector;
import nz.this.is.absolute.crap.selector.SelectorItem;
import nz.this.is.absolute.crap.server.BatchValidator;
import nz.this.is.absolute.crap.server.Validatable;
import nz.this.is.absolute.crap.server.ValidationException;
import nz.this.is.absolute.crap.server.business.BusinessObject;
import nz.this.is.absolute.crap.server.database.EntityHandler;
import nz.this.is.absolute.crap.server.database.SQLEntityHandler;

import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

/**
 * The Class BatchManager.
 */
public class BatchManager extends XMLEntity {

	private static final Logger logger = Logger.getLogger(BatchManager.class);
	
	/** The Constant DOCUMENT. */
	private final static String DOCUMENT = "Batches.xml";

	/**
	 * The Class BatchDescriptor.
	 */
	public class BatchDescriptor extends XMLEntity {

		/** The batchSelectors. */
		private final Collection<String> batchSelectors = new ArrayList<String>();

		/** The dependentCollections. */
		private final Collection<String> dependentCollections = new ArrayList<String>();

		/** The directSelectors. */
		private final Collection<String> directSelectors = new ArrayList<String>();

		/** The postTo. */
		private String postTo;

		/** The properties. */
		private final Collection<String> properties = new ArrayList<String>();

		/**
		 * Gets the batch selectors iterator.
		 * 
		 * @return the batch selectors iterator
		 */
		public Iterator<String> getBatchSelectorsIterator() {
			return this.batchSelectors.iterator();
		}

		/**
		 * Gets the dependent collections iterator.
		 * 
		 * @return the dependent collections iterator
		 */
		public Iterator<String> getDependentCollectionsIterator() {
			return this.dependentCollections.iterator();
		}

		/**
		 * Gets the post to.
		 * 
		 * @return the post to
		 */
		public String getPostTo() {
			return this.postTo;
		}

		/**
		 * Gets the post to business object.
		 * 
		 * @param businessObject
		 *            the business object
		 * @param postHandler
		 *            the post handler
		 * 
		 * @return the post to business object
		 * 
		 * @throws ValidationException
		 *             the validation exception
		 */
		private BusinessObject getPostToBusinessObject(
				BusinessObject businessObject, EntityHandler postHandler)
				throws ValidationException {
			if (this.postTo == null) {
				return null;
			}
			final BusinessObject postToBusinessObject = businessObject
					.getBusinessObjectFromMap(this.postTo, postHandler);
			// copy properties
			for (final String propertyName : this.properties) {
				String postToPropertyName;
				if ("postToStatus".equals(propertyName)) {
					// status field on batch entity refers to the batch entity
					// itself
					// so postToStatus is used for updating the status property
					// of the postToBusinessObject itself
					postToPropertyName = "status";
				} else {
					postToPropertyName = propertyName;
				}
				final SelectorItem destinationItem = postToBusinessObject
						.find(postToPropertyName);
				if (destinationItem != null) {
					final Object oldValue = destinationItem.getValue();
					final Object newValue = businessObject.get(propertyName);
					if (SafeComparator.areDifferent(oldValue, newValue)) {
						destinationItem.setValue(newValue);
					}
				}
			}
			// copy direct selectors
			for (final String selectorName : this.directSelectors) {
				final SelectorItem destinationItem = postToBusinessObject
						.find(selectorName);
				if (destinationItem != null) {
					// get the old and new values for the selectors
					Selector oldSelector = (Selector) destinationItem
							.getValue();
					Selector newSelector = (Selector) businessObject
							.get(selectorName);
					// strip them down to bare identifiers for comparison
					if (oldSelector != null) {
						oldSelector = oldSelector.getAsIdentifier();
					}
					if (newSelector != null) {
						newSelector = newSelector.getAsIdentifier();
					}
					// if they're different then update
					if (SafeComparator.areDifferent(oldSelector, newSelector)) {
						destinationItem.setValue(newSelector);
					}
				}
			}
			// copy batch selectors
			for (final String batchSelectorName : this.batchSelectors) {
				final Selector batchSelector = (Selector) businessObject
						.get(batchSelectorName);
				if (batchSelector == null) {
					throw new ValidationException(
							"\"PostTo\" selector missing.");
				}
				final BusinessObject batchObject = postHandler
						.find(batchSelector);
				if (batchObject != null) {
					// get the postTo selector for the batch object we depend on
					final BatchDescriptor batchDescriptor = batchMap
							.get(batchObject.getName());
					if (batchDescriptor.postTo != null
							&& postToBusinessObject
									.containsKey(batchDescriptor.postTo)) {
						final Selector realSelector = batchObject
								.getBusinessObjectFromMap(
										batchDescriptor.postTo, postHandler);
						postToBusinessObject.put(batchDescriptor.postTo,
								realSelector);
					}
				}
			}
			businessObject.put(this.postTo, postToBusinessObject);
			return postToBusinessObject;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * nz.this.is.absolute.crap.sax.XMLEntity#initChild(java.lang.String,
		 * java.lang.String, java.lang.String, org.xml.sax.Attributes)
		 */
		@Override
		protected ContentHandler initChild(String uri, String localName,
				String qName, Attributes attributes) throws SAXException {
			if ("Properties".equals(qName)) {
				return new XMLEntity() {
					@Override
					protected ContentHandler initChild(String uri,
							String localName, String qName,
							Attributes attributes) throws SAXException {
						BatchDescriptor.this.properties.add(attributes
								.getValue("name"));
						return null;
					}
				};
			} else if ("DirectSelectors".equals(qName)) {
				return new XMLEntity() {
					@Override
					protected ContentHandler initChild(String uri,
							String localName, String qName,
							Attributes attributes) throws SAXException {
						BatchDescriptor.this.directSelectors.add(attributes
								.getValue("name"));
						return null;
					}
				};
			} else if ("BatchSelectors".equals(qName)) {
				return new XMLEntity() {
					@Override
					protected ContentHandler initChild(String uri,
							String localName, String qName,
							Attributes attributes) throws SAXException {
						BatchDescriptor.this.batchSelectors.add(attributes
								.getValue("name"));
						return null;
					}
				};
			} else if ("PostTo".equals(qName)) {
				return new XMLEntity() {
					@Override
					protected ContentHandler initChild(String uri,
							String localName, String qName,
							Attributes attributes) throws SAXException {
						BatchDescriptor.this.postTo = attributes
								.getValue("name");
						return null;
					}
				};
			} else if ("DependentCollections".equals(qName)) {
				return new XMLEntity() {
					@Override
					protected ContentHandler initChild(String uri,
							String localName, String qName,
							Attributes attributes) throws SAXException {
						BatchDescriptor.this.dependentCollections
								.add(attributes.getValue("name"));
						return null;
					}
				};
			}
			return null;
		}
	}

	/** The batchMap. */
	private static Map<String, BatchDescriptor> batchMap = new HashMap<String, BatchDescriptor>();

	/**
	 * Gets the.
	 * 
	 * @param batchName
	 *            the batch name
	 * 
	 * @return the batch descriptor
	 */
	public static BatchDescriptor get(String batchName) {
		return batchMap.get(batchName);
	}

	/**
	 * Gets the post to selector name.
	 * 
	 * @param batchName
	 *            the batch name
	 * 
	 * @return the post to selector name
	 */
	public static String getPostToSelectorName(String batchName) {
		final BatchDescriptor batchDescriptor = batchMap.get(batchName);
		if (batchDescriptor == null) {
			return null;
		}
		return batchDescriptor.getPostTo();
	}

	// singleton instance so that static batch map can be initialised using
	// xml
	/** The Constant singleton. */
	@SuppressWarnings("unused")
	private static final Object singleton = new BatchManager();

	/**
	 * Post.
	 * 
	 * @param businessObject
	 *            the business object
	 * 
	 * @throws Exception
	 *             the exception
	 */
	public static void post(BusinessObject businessObject) throws Exception {
		// validate the batch root object only - it can validate the rest if it
		// needs to
		
		if (businessObject instanceof Validatable) {
			if (!BatchValidator.validate(businessObject)) {
				logger.warn(String.format("Validating %s failed", businessObject.getClass().getSimpleName()));
				throw new ValidationException(
						"Batch did not validate - it was not posted");
			}
		
			((Validatable) businessObject).validator().prepareToPost();
		}
		final SQLEntityHandler postHandler = new SQLEntityHandler(true);
		final Iterator<BusinessObject> batchIterator = new BatchIterator(
				businessObject, null, postHandler);
		// iterate through batch again posting each object
		try {
			while (batchIterator.hasNext()) {
				post(batchIterator.next(), postHandler);
			}
			postHandler.commit();
		} catch (final Exception e) {
			logger.error("Exception occurred while posting batches", e);
			// something went wrong
			postHandler.rollback();
			throw e;
		}
		return;
	}

	/**
	 * Post.
	 * 
	 * @param businessObject
	 *            the business object
	 * @param postHandler
	 *            the post handler
	 * 
	 * @throws KupengaException
	 *             the kupenga exception
	 */
	private static void post(BusinessObject businessObject,
			EntityHandler postHandler) throws KupengaException {
		if (businessObject == null) {
			return;
		}
		if (Boolean.TRUE.equals(businessObject.get("posted"))) {
			return;
		}
		final BatchDescriptor batchDescriptor = batchMap.get(businessObject
				.getName());
		final BusinessObject postToBusinessObject = batchDescriptor
				.getPostToBusinessObject(businessObject, postHandler);
		if (postToBusinessObject != null) {
			postToBusinessObject.save(postHandler);
		}
		businessObject.setItemValue("posted", Boolean.TRUE);
		businessObject.save(postHandler);
	}

	/**
	 * Instantiates a new batch manager.
	 */
	private BatchManager() {
		try {
			final XMLReader xmlReader = XMLReaderFactory.createXMLReader();
			xmlReader.setContentHandler(this);
			xmlReader.parse(new InputSource(this.getClass().getClassLoader().getResourceAsStream("templates/" + DOCUMENT)));
		} catch (final Exception e) {
			logger.error("Error parsing Batch XML.", e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see nz.this.is.absolute.crap.sax.XMLEntity#initChild(java.lang.String,
	 * java.lang.String, java.lang.String, org.xml.sax.Attributes)
	 */
	@Override
	protected ContentHandler initChild(String uri, String localName,
			String qName, Attributes attributes) throws SAXException {
		final BatchDescriptor batchDescriptor = new BatchDescriptor();
		// put it in the map
		batchMap.put(attributes.getValue("name"), batchDescriptor);
		return batchDescriptor;
	}
}
[Advertisement] Keep all your packages and Docker containers in one place, scan for vulnerabilities, and control who can access different feeds. ProGet installs in minutes and has a powerful free version with a lot of great features that you can upgrade when ready.Learn more.

CodeSOD: Back Up for a Moment

Jul. 14th, 2025 06:30 am
[syndicated profile] the_daily_wtf_feed

Posted by Remy Porter

James's team has a pretty complicated deployment process implemented as a series of bash scripts. The deployment is complicated, the scripts doing the deployment are complicated, and failures mid-deployment are common. That means they need to gracefully roll back, and they way they do that is by making backup copies of the modified files.

This is how they do that.

DATE=`date '+%Y%m%d'`
BACKUPDIR=`dirname ${DESTINATION}`/backup
if [ ! -d $BACKUPDIR ]
then
        echo "Creating backup directory ..."
        mkdir -p $BACKUPDIR
fi
FILENAME=`basename ${DESTINATION}`
BACKUPFILETYPE=${BACKUPDIR}/${FILENAME}.${DATE}
BACKUPFILE=${BACKUPFILETYPE}-1
if [ -f ${BACKUPFILE} ] || [ -f ${BACKUPFILE}.gz ] ; then BACKUPFILE=${BACKUPFILETYPE}-2 ; fi
if [ -f ${BACKUPFILE} ] || [ -f ${BACKUPFILE}.gz ] ; then BACKUPFILE=${BACKUPFILETYPE}-3 ; fi
if [ -f ${BACKUPFILE} ] || [ -f ${BACKUPFILE}.gz ] ; then BACKUPFILE=${BACKUPFILETYPE}-4 ; fi
if [ -f ${BACKUPFILE} ] || [ -f ${BACKUPFILE}.gz ] ; then BACKUPFILE=${BACKUPFILETYPE}-5 ; fi
if [ -f ${BACKUPFILE} ] || [ -f ${BACKUPFILE}.gz ] ; then BACKUPFILE=${BACKUPFILETYPE}-6 ; fi
if [ -f ${BACKUPFILE} ] || [ -f ${BACKUPFILE}.gz ] ; then BACKUPFILE=${BACKUPFILETYPE}-7 ; fi
if [ -f ${BACKUPFILE} ] || [ -f ${BACKUPFILE}.gz ] ; then BACKUPFILE=${BACKUPFILETYPE}-8 ; fi
if [ -f ${BACKUPFILE} ] || [ -f ${BACKUPFILE}.gz ] ; then BACKUPFILE=${BACKUPFILETYPE}-9 ; fi
if [ -f ${BACKUPFILE} ] || [ -f ${BACKUPFILE}.gz ] ; then
cat <<EOF
You have already had 9 rates releases in one day.

${BACKUPFILE} already exists, do it manually !!!
EOF
exit 2
fi

Look, I know that loops in bash can be annoying, but they're not that annoying.

This code creates a backup directory (if it doesn't already exist), and then creates a file name for the file we're about to backup, in the form OriginalName.Ymd-n.gz. It tests to see if this file exists, and if it does, it increments n by one. It does this until either it finds a file name that doesn't exist, or it hits 9, at which point it gives you a delightfully passive aggressive message:

You have already had 9 rates releases in one day. ${BACKUPFILE} already exists, do it manually !!!

Yeah, do it manually. Now, admittedly, I don't think a lot of folks want to do more than 9 releases in a given day, but there's no reason why they couldn't just keep trying until they find a good filename. Or even better, require each release to have an identifier (like the commit or build number or whatever) and then use that for the filenames.

Of course, just fixing this copy doesn't address the real WTF, because we laid out the real WTF in the first paragraph: deployment is a series of complicated bash scripts doing complicated steps that can fail all the time. I've worked in places like that, and it's always a nightmare. There are better tools! Our very own Alex has his product, of course, but there are a million ways to get your builds repeatable and reliable that don't involve BuildMaster but also don't involve fragile scripts. Please, please use one of those.

[Advertisement] Plan Your .NET 9 Migration with Confidence
Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!

Error'd: Another One Rides the Bus

Jul. 11th, 2025 06:30 am
[syndicated profile] the_daily_wtf_feed

Posted by Lyle Seaman

"Toledo is on Earth, Adrian must be on Venus," remarks Russell M. , explaining "This one's from weather.gov. Note that Adrian is 28 million miles away from Toledo. Being raised in Toledo, Michigan did feel like another world sometimes, but this is something else." Even Toledo itself is a good bit distant from Toledo. Definitely a long walk.

2

 

"TDSTF", reports regular Michael R. from London, well distant from Toledo OH and Toledo ES.

1

 

Also on the bus, astounded Ivan muses "It's been a long while since I've seen a computer embedded in a piece of public infrastructure (here: a bus payment terminal) literally snow crash. They are usually better at listening to Reason..."

3

 

From Warsaw, Jaroslaw time travels twice. First with this entry "Busses at the bus terminus often display time left till departure, on the front display and on the screens inside. So one day I entered the bus - front display stating "Departure in 5 minutes". Inside I saw this (upper image)... After two minutes the numbers changed to the ones on the lower image. I'm pretty sure I was not sitting there for six hours..."

0

 

And again with an entry we dug out of the way back bin while I was looking for more bus-related items. Was it a total concidence this bus bit also came from Jaroslaw? who just wanted to know "Is bus sharing virtualised that much?" I won't apologize, any kind of bus will do when we're searching hard to match a theme.

4

 

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
[syndicated profile] raspberry_pi_feed

Posted by Sophie Ashford

We love hearing from members of the community and sharing stories of amazing young people, volunteers, and educators who are using their passion for technology to create positive change in the world around them.

It’s especially inspiring to hear about young people who are not only passionate about technology, but who are also driven to share that passion with others. Meet Matthew, a 15-year-old creator and youth mentor at Code Club, who builds his own projects and inspires peers by organising hackathons.

Matthew and his team at Cool as Hack at the RPF offices
Matthew and his team at Cool as Hack at the RPF offices

Matthew’s early experience with coding 

Matthew’s journey into the world of coding began at a young age. His initial exposure was through Scratch at school in Singapore. From there, he began exploring self-learn platforms in his own time, getting to grips with HTML and basic web development.

His enthusiasm for creating led him to participate in a technology week in Year 6, where he took on a BBC micro:bit challenge. He dedicated his summer holiday to developing a token system that encouraged community recycling, using an ultrasonic sensor to award points for good behaviour. This early project showcased his knack for problem-solving and innovation.

What truly captivated Matthew was the possibility of combining the logical challenges of competitive programming with the joy of project creation.

Matthew with his device developed in Year 6 to promote recycling behaviour in his residential community
Matthew with his device developed in Year 6 to promote recycling behaviour in his residential community

Connecting with the community

Through Youthhacks, an initiative he co-founded to support teenage hackathon organisers, Matthew aims to expand access to hackathons across the UK (a hackathon is an event where individuals or teams work intensively over a relatively short time period to build software, hardware, or other kinds of technology). Matthew wants to offer advice and support, making it easier for young people to run their own hackathons. He puts a lot of time into ensuring that the content and atmosphere truly resonate with the participants.

“So, we made Youthhacks basically as an idea to be able to support these teenage organisers, you know, like hackathons for teenagers by teenagers.”

Matthew’s connection with the Raspberry Pi Foundation came from his keen interest in the hackathon community and a need for a local venue. Having previously toured the Foundation’s offices for a school robotics club, he decided to reach out when organising a satellite hackathon called Counterspell.

This initial collaboration led to further events at the Foundation, including Scrapyard Cambridge and, more recently, Cool as Hack.

Coolest Projects hackathon: A new approach to collaborative coding 

Cool as Hack was Matthew’s third event held at the Raspberry Pi Foundation offices. Unlike traditional hackathons with intense time pressure, this event, inspired by the spirit of Coolest Projects, aimed to be more relaxed and collaborative. 

“For this, people could bring in their own project scraps and then they could put it together with a team, finalise it, and then enter it to Coolest Projects.” 

The focus was on showcasing creativity and sharing projects globally, rather than competitive prizes. Everyone then entered their creations into the Coolest Projects online showcase.

Young coders at Cool as Hack
Cool as Hack in progress at RPF HQ. Credit: W O Wallace

Cool as Hack was a huge success. The atmosphere was incredible — there was even a karaoke session and a “swag shop” where participants could exchange tokens earned for innovative ideas or project milestones. This token system, designed by Matthew and harking back to his own recycling project from years ago, created a fun and engaging reward system.

Inspiring the next generation

Matthew’s drive to organise these events and encourage other young people to code stems from his enjoyment of project creation and the community aspect of hackathons. 

“Well, I suppose it links back to me enjoying making projects and when you attend a hackathon, it’s not a competition really. It’s more of a social event. So, you’re making a project and then you’re meeting quite a lot of coders, or even artists and musicians, and so many other people.”

Young coders at Cool as Hack at the RPF offices
All of the creators that took part in Cool as Hack. Credit: W O Wallace

Now a regular volunteer at the Raspberry Pi Foundation’s monthly Code Club in Cambridge, Matthew remains focused on encouraging others into tech. For aspiring young coders, he says that coding is far more diverse and creative than many might initially perceive, encompassing art, storytelling, and problem-solving. Matthew’s advice is simple: 

“Enjoy the process and as you learn new things you’ll realise that all of this is like super interesting, and that there are so many ways to make what you want. Just enjoy it and continue meeting new people and, yeah, be creative.” 

Matthew’s journey shows how an intro to computing at a young age can lead to an incredible amount of impact. With his continued dedication, he’s sure to inspire many more young minds to start on their own coding adventures.

If you would like to explore coding, you can get started at home with over 250 free projects

Looking for a little extra support in your own coding journey or open to mentoring others? Join a Code Club near you to meet a like-minded and supportive community.

The post Code, karaoke, and creativity: Meet Matthew appeared first on Raspberry Pi Foundation.

The Middle(ware) Child

Jul. 10th, 2025 06:30 am
[syndicated profile] the_daily_wtf_feed

Posted by Ellis Morning

Once upon a time, there was a bank whose business relied on a mainframe. As the decades passed and the 21st century dawned, the bank's bigwigs realized they had to upgrade their frontline systems to applications built in Java and .NET, but—for myriad reasons that boiled down to cost, fear, and stubbornness—they didn't want to migrate away from the mainframe entirely. They also didn't want the new frontline systems to talk directly to the mainframe or vice-versa. So they tasked old-timer Edgar with writing some middleware. Edgar's brainchild was a Windows service that took care of receiving frontline requests, passing them to the mainframe, and sending the responses back.

Edgar's middleware worked well, so well that it was largely forgotten about. It outlasted Edgar himself, who, after another solid decade of service, moved on to another company.

Waiting, pastel on paper, 1880–1882

A few years later, our submitter John F. joined the bank's C# team. By this point, the poor middleware seemed to be showing its age. A strange problem had arisen: between 8:00AM and 5:00PM, every 45 minutes or so, it would lock up and have to be restarted. Outside of those hours, there was no issue. The problem was mitigated by automatic restarts, but it continued to inflict pain and aggravation upon internal users and external customers. A true solution had to be found.

Unfortunately, Edgar was long gone. The new "owner" of the middleware was an infrastructure team containing zero developers. Had Edgar left them any documentation? No. Source code? Sort of. Edgar had given a copy of the code to his friend Bob prior to leaving. Unfortunately, Bob's copy was a few point releases behind the version of middleware running in production. It was also in C, and there were no C developers to be found anywhere in the company.

And so, the bank's bigwigs cobbled together a diverse team of experts. There were operating system people, network people, and software people ... including the new guy, John. Poor John had the unenviable task of sifting through Edgar's source code. Just as the C# key sits right next to the C key on a piano, reasoned the bigwigs, C# couldn't be that different from C.

John toiled in an unfamiliar language with no build server or test environment to aid him. It should be no great surprise that he got nowhere. A senior coworker suggested that he check what Windows' Process Monitor registered when the middleware was running. John allowed a full day to pass, then looked at the results: it was now clear that the middleware was constantly creating and destroying threads. John wrote a Python script to analyze the threads, and found that most of them lived for only seconds. However, every 5 minutes, a thread was created but never destroyed.

This only happened during the hours of 8:00AM to 5:00PM.

At the next cross-functional team meeting behind closed doors, John finally had something of substance to report to the large group seated around the conference room table. There was still a huge mystery to solve: where were these middleware-killing threads coming from?

"Wait a minute! Wasn't Frank doing something like that?" one of the other team members piped up.

"Frank!" A department manager with no technical expertise, who insisted on attending every meeting regardless, darted up straight in his chair. For once, he wasn't haranguing them for their lack of progress. He resembled a wolf who'd sniffed blood in the air. "You mean Frank from Accounting?!"

This was the corporate equivalent of an arrest warrant. Frank from Accounting was duly called forth.

"That's my program." Frank stood before the table, laid back and blithe despite the obvious frayed nerves of several individuals within the room. "It queries the middleware every 5 minutes."

They were finally getting somewhere. Galvanized, John's heart pounded. "How?" he asked.

"Well, it could be that the middleware is down, so first, my program opens a connection just to make sure it's working," Frank explained. "If that works, it opens another connection and sends the query."

John's confusion mirrored the multiple frowns that filled the room. He forced himself to carefully parse what he'd just heard. "What happens to the first connection?"

"What do you mean?" Frank asked.

"You said your program opens two connections. What do you do with the first one?"

"Oh! I just use that one to test whether the middleware is up."

"You don't need to do that!" one of the networking experts snarled. "For Pete's sake, take that out of your code! Don't you realize you're tanking this thing for everyone else?"

Frank's expression made clear that he was entirely oblivious to the chaos wrought by his program. Somehow, he survived the collective venting of frustration that followed within that conference room. After one small update to Frank's program, the middleware stabilized—for the time being. And while Frank became a scapegoat and villain to some, he was a hero to many, many more. After all, he single-handedly convinced the bank's bigwigs that the status quo was too precarious. They began to plan out a full migration away from mainframe, a move that would free them from their dependence upon aging, orphaned middleware.

Now that the mystery had been solved, John knew where to look in Edgar's source code. The thread pool had a limit of 10, and every thread began by waiting for input. The middleware could handle bad input well enough, but it hadn't been written to handle the case of no input at all.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
[syndicated profile] raspberry_pi_feed

Posted by Sean Sayers

The Hello World podcast is back, accompanying the latest issue of Hello World magazine. This new three-part miniseries explores some of the topics from issue 27 of Hello World, which focuses on integrating computing education across the curriculum.

Whether you’re a seasoned educator or just starting your journey with computing education, this podcast audio and video series is full of insights, inspiration, and practical tips from educators and experts around the world.

If you’re already subscribed, the new episodes will appear automatically in your favourite podcast app every Tuesday.

Episode 1: Why kids still need to learn to code in the age of AI

Out now

In our first episode, Raspberry Pi Foundation CEO Philip Colligan, CBE, sits down with teacher Janine Kirk to discuss why, in the age of AI, it’s more important than ever for young people to learn to code. Their conversation draws on ideas from our downloadable position paper, which is also featured in issue 27 of Hello World magazine.

Episode 2: Voices & tips from CSTA conference

Released Tuesday 15 July

Photo of Hello World editor, Meg Wang, and contributing editor Dominick Sanders at CSTA 2025.

Next week, we’ll bring you the buzz from the Computer Science Teachers Association’s annual conference in Cleveland, USA. We’re speaking with educators at the conference to hear how they’re integrating computer science across subjects, and you’ll hear their top classroom tips for teaching CS in context.

Episode 3: Global perspectives on AI education

Released Tuesday 22 July

Episode 3 of the Hello World Podcast set

The miniseries wraps up with an in-depth discussion about AI education around the world. Hosted by Ben Garside, Senior Learning Manager for Experience AI, the conversation features Leonida Soi, Learning Manager in Kenya; Monika Katkute-Gelzine, CEO of Vedliai in Lithuania; and Aimy Lee, COO of Penang Science Cluster in Malaysia. Monika and Aimy work with us in our global Experience AI partner programme.

Listen, read, learn, subscribe, and share

Each of these three podcast episode builds on the themes in the latest Hello World issue, where you’ll find inspiration and practical tips from educators who are integrating CS across a variety of subjects and for all school ages.

Subscribe to the Hello World podcast wherever you get your podcasts to never miss an episode, and to help us reach more teachers. If you’re subscribe to Hello World magazine (it’s free), we’ll also let you know when new podcast episodes are available.

And, don’t forget to share this new podcast series with your fellow educators.

The post New Hello World podcast series: Bringing computer science into every classroom appeared first on Raspberry Pi Foundation.

CodeSOD: The XML Dating Service

Jul. 9th, 2025 06:30 am
[syndicated profile] the_daily_wtf_feed

Posted by Remy Porter

One of the endless struggles in writing reusable API endpoints is creating useful schemas to describe them. Each new serialization format comes up with new ways to express your constraints, each with their own quirks and footguns and absolute trainwrecks.

Maarten has the "pleasure" of consuming an XML-based API, provided by a third party. It comes with an XML schema, for validation. Now, the XML Schema Language has a large number of validators built in. For example, if you want to restrict a field to being a date, you can mark it's type as xsd:date. This will enforce a YYYY-MM-DD format on the data.

If you want to ruin that validation, you can do what the vendor did:

<xsd:simpleType name="DatumType">
  <xsd:annotation>
    <xsd:documentation>YYYY-MM-DD</xsd:documentation>
  </xsd:annotation>
  <xsd:restriction base="xsd:date">
    <xsd:pattern value="(1|2)[0-9]{3}-(0|1)[0-9]-[0-3][0-9]" />
  </xsd:restriction>
</xsd:simpleType>

You can see the xsd:pattern element, which applies a regular expression to validation. And this regex will "validate" dates, excluding things which are definitely not dates, and allowing very valid dates, like February 31st, November 39th, and the 5th of Bureaucracy (the 18th month of the year), as 2025-02-31, 2025-11-39 and 2025-18-05 are all valid strings according to the regex.

Now, an astute reader will note that this is a xsd:restriction on a date; this means that it's applied in addition to ensuring the value is a valid date. So this idiocy is harmless. If you removed the xsd:pattern element, the behavior would remain unchanged.

That leads us to a series of possible conclusions: either they don't understand how XML schema restrictions work, or they don't understand how dates work. As to which one applies, well, I'd say 1/3 chance they don't understand XML, 1/3 chance they don't understand dates, and a 1/3 chance they don't understand both.

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.
[syndicated profile] raspberry_pi_feed

Posted by Sean Sayers

We think computing or computer science (CS) needs to be accessible to all learners, and we know that teachers work hard towards this. Traditional CS approaches can lack flexibility, creating barriers to learning and excluding some young people. In today’s blog, we’re highlighting the ‘Universal design for learning’ (UDL) framework and how you can use it to make computing education more accessible to all your learners.

Children in the classroom learning  Computer Science

We also share our new UDL-focused Pedagogy Quick Read, which you can download for free to:

  • Find practical tips for how to use the UDL framework and related approaches with your learners
  • Read a summary of the research behind the framework

Universal Design for Learning: Because one size does not fit all

Everyone is different and has their own way of learning. What works for one young person may not work for the next. So why should we expect learners to be taught the same material in the same way? 

Todd Rose, a contributor to the UDL framework, highlights the factors involved with a young person’s ability to engage and participate in learning. These include cognitive, social-emotional, family background and academic factors. He dispels the idea of an “average” learner, and instead suggests the concept of learner variability. 

Picture of our new UDL-focused Pedagogy Quick Read
The new Quick Read

As educators, it’s important to consider that students will likely be at different stages of understanding, and a one-size-fits-all approach isn’t suitable. The UDL framework avoids this mindset and provides teachers with structured guidelines to design accessible lessons from the beginning. 

What is the UDL framework?

The UDL framework encourages educators to provide flexibility for learners in three areas: 

  • Multiple means of engagement: The “why of learning”, which helps to pique students’ curiosity and motivates them to stay engaged
  • Multiple means of representation: The “what of learning”, which focuses on presenting information in different ways to make the content accessible
  • Multiple means of action and expression: The “how of learning”, which relates to different ways for students to access learning and express their understanding

How can I apply the UDL framework?

Two things are key while you are planning how to apply the UDL framework with your learners:

  • Try not to introduce all three areas at once to your practice. Instead, focus on one area of the framework at a time and reflect to identify where there might be gaps. Focus on these first and make changes one by one.
  • Consider how different approaches will work for different groups and individuals. Try to identify what works for your learners and vary or adapt your approach as necessary.

Applying UDL: Some ideas for teaching programming

Multiple means of engagement — show learners different reasons for engaging in programming. For example:

  • Solving real-life problems
  • Interest in technology or logical thinking
  • Creative expression

Multiple means of representation — teach programming concepts in multiple ways. For example:

  • Demonstrate through live coding
  • Write on a blackboard with a flowchart
  • Let learners label and assemble bits of paper into a ‘program’

Multiple means of action and expression — teach with accessibility in mind. For example:

  • Use tools appropriate for learners’ mouse and keyboard skills
  • Let learners demonstrate their understanding in different ways (e.g. verbally, by writing/drawing, by creating a program)

The UDL framework aligns closely with several key research-supported pedagogies that you can use for effective instruction in computational thinking and programming. For example, the pedagogy approach ‘Use-Modify-Create’ (UMC) can be paired with the UDL categories. The new Quick Read explores these connections in more detail.

Students in the classroom

The benefits of the UDL framework

Potential benefits for teachers:

  • The framework provides a clear structure for designing learning activities that appeal to and engage the widest set of learners
  • It can help you consider all the ways you might engage your learners and make CS lessons more accessible.
  • UDL encourages you to reflect on the different ways in which you might represent concepts and ideas
  • It can help you to build learner agency and independence in your students by offering them different ways to express their learning in CS topics. 

Potential benefits for learners:

  • The framework promotes a sense of ownership over their learning. Which can boost their motivation and resilience to sticking with difficult challenges. 
  • They will likely find content that resonates with them, leading to higher engagement and therefore learning.
  • They will be able to demonstrate their CS knowledge confidently and engage limitlessly in CS contexts.

Our new Quick Read shares tips on how to best use the framework in your teaching. 

Inclusive computer science: The wider context

We know there is a lack of representation within the field of CS. Our recent position paper ‘Why kids still need to learn to code in the age of AI’ and an episode of the  Hello World podcast, ‘How can we empower girls in computing’ touched on this. Both highlight why it’s important that learners from all backgrounds are empowered to contribute their perspectives and experiences and shape the future with computing.

Photo from the Hello World podcast, ‘How can we empower girls in computing
Guests and host during the recording of our ‘How can we empower girls in computing’ episode

“The reality is that access to the opportunities to learn about computer science, programming, and coding has remained deeply unequal, both within and between countries. That has helped create a technology sector that doesn’t reflect the broad diversity of human backgrounds, perspectives, and experiences. And we are all living with the consequences.” – Philip Colligan, Mark Griffiths, Veronica Cucuiat

“If we don’t have a diverse range of people designing and implementing that tech, then we are going to come across issues.” – Becky Patel, Tech She Can, Hello World podcast”

By embracing the principles of ‘Universal design for learning’ and similar approaches, we can create a more inclusive and equitable learning environment in computer science for everyone.

The post How to build young people’s agency through accessible learning appeared first on Raspberry Pi Foundation.

CodeSOD: Off Color

Jul. 8th, 2025 06:30 am
[syndicated profile] the_daily_wtf_feed

Posted by Remy Porter

Carolyn inherited a somewhat old project that had been initiated by a "rockstar" developer, and then passed to developer after developer over the years. They burned through rockstars faster than Spinal Tap goes through drummers. The result is gems like this:

private void init(){
	ResourceHelper rh = new ResourceHelper();
	for ( int i = 0; i < 12; i++) {
		months[i] = rh.getResource("calendar."+monthkeys[i]+".long");
		months_s[i] = rh.getResource("calendar."+monthkeys[i]+".short");
	}
	StaticData data = SomeService.current().getStaticData();
	this.bankHolidayList = data.getBankHolidayList();
	colors.put("#dddddd", "#dddddd");
	colors.put("#cccccc", "#cccccc");
	colors.put("#e6e6e6", "#e6e6e6");
	colors.put("#ff0000", "#ffcccc");
	colors.put("#ffff00", "#ffffcc");
	colors.put("#00ff00", "#ccffcc");
	colors.put("#5050ff", "#ccccff");
	colors.put("#aa0000", "#ff9999");
	colors.put("#ff8000", "#ffcc99");
	colors.put("#99ff99", "#ccffcc");
	colors.put("#ffcc99", "#ffffcc");
	colors.put("#ff9966", "#ffcc99");
	colors.put("#00c040", "#99cc99");
	colors.put("#aadddd", "#ccffff");
	colors.put("#e0e040", "#ffff99");
	colors.put("#6699ff", "#99ccff");
}

There are plenty of things in this function that raise concerns- whatever is going on with the ResourceHelper and the monthkeys array, for example. But let's just breeze past that into that colors lookup table, because boy oh boy.

There's the obvious issue of using server-side code to manage colors instead of CSS, which is bad, sure. But this translation table which converts some colors (presumably already used in the display?) to some other colors (presumably to replace the display colors) is downright mystifying. How did this happen? Why did this happen? What happens when we attempt to apply a color not in the lookup table?

I want to say more mean things about this, but the more I stare at the original colors and what they get translated to, I think this lookup table is trying to tell me I should…


lighten up.

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
[syndicated profile] raspberry_pi_feed

Posted by Meg Wang

While in some countries, such as England, computing is taught as a standalone subject, in others, like the USA, computing concepts are integrated across the school curriculum. In our brand-new issue of Hello World, out today for free, educators share ways to integrate computer science into your classroom.

Hello World Issue 27 front cover

Integrating CS to broaden participation

The argument for making computing and computer science (CS) standalone has often been about quality. We’ve heard educators say that teaching CS as part of other subjects can be hard, especially if you don’t have a CS background. On the other hand, integrating computer science into other subjects can offer a more accessible entry point for young people, broadening participation in CS education. And the critical thinking and problem-solving skills young people gain through computer science can enhance their learning of any subject. 

As digital technology increasingly shapes our world, it may be that thoughtful cross-curricular CS education is the most effective way to empower all young people to become confident and critical technology users.

Issue 27 of Hello World features a range of practical articles with ideas for integrating CS over a variety of subjects at the primary, elementary, and high-school levels.

For example:

  • James Abela shares how to teach coding across the curriculum using OctoStudio and the concepts of sequence, selection, and repetition
  • Jesualdo Martínez Molina presents hands-on examples of weaving together cross-curricular and modern foreign languages in the primary classroom
  • Jane Waite introduces the Autonomy framework, which explores whether we can effectively teach two things at once

Also in this issue:

  • Laurie Gale introduces PRIMMDebug, a new way to teach debugging
  • Teresa Harris Boag defines strategies for a whole-school approach to artificial intelligence (AI) to engage parents and school staff in developing an effective AI strategy
  • Tiffany Jones shares how she ensures that students can see themselves in tech

And much, much more.

Jake Baskin, Executive Director of the Computer Science Teachers Association, says in this issue of Hello World: “If you’re a teacher who is implementing CS principles in your classroom, you are a computer science teacher.”

Whether CS is your specialist subject or not, Hello World is full of ideas from your fellow educators on how to inspire your students. 

New podcast series

The Hello World podcast is also back, with a miniseries in audio and video focused on integrated CS. If you’re subscribed via a podcast app, the three new episodes will show up in your feed on Tuesdays. Or you can already listen to the new episodes today via the exclusive links inside issue 27.

Hello World Editor: Meg Wang, presenting an episode of the Hello World Podcast

Share your thoughts & subscribe to Hello World

We hope you enjoy this issue of Hello World. Please get in touch with your article ideas or what you would like to see in the magazine.

  • Subscribe to Hello World for free to never miss a magazine issue
  • Subscribe to the Hello World podcast using your podcast app of choice
  • Share your thoughts and ideas about the new Hello World issue and episodes with us via the Raspberry Pi Foundation social media channels
  • Find out how you can write for the magazine

The post Hello World 27 out now: Integrated computer science appeared first on Raspberry Pi Foundation.

CodeSOD: All Locked Up

Jul. 7th, 2025 06:30 am
[syndicated profile] the_daily_wtf_feed

Posted by Remy Porter

Dan was using a third-party database which provided a PHP API. At one point, Dan was running into an issue where he actually needed locks on the database. Fortunately for him, the vendor documentation told him that there was a method called obtainRowLock.

obtainRowLock($table, $where) - Attempt to lock a row, will escalate and lock the table if row locking is not supported, will escalate and lock the database if table locking is not supported; returns true on success, false on failure
$table - name of table to lock
$where - WHERE clause to define rows, ex: "WHERE id=52". If left empty, function will assume a table lock

That was exactly what Dan needed, so he called it. It returned false, implying a failure. He changed the parameters. He discarded his where clause. He tried all sorts of things, and it always returned false. So he dug into the source code, to see how it actually worked.

function obtainRowLock($table, $where)
{
  return false;
}

Is it truly a failure if you don't even try?

[Advertisement] Keep all your packages and Docker containers in one place, scan for vulnerabilities, and control who can access different feeds. ProGet installs in minutes and has a powerful free version with a lot of great features that you can upgrade when ready.Learn more.

Error'd: Better Nate Than Lever

Jul. 4th, 2025 10:40 am
[syndicated profile] the_daily_wtf_feed

Posted by Lyle Seaman

Happy Friday. For those of us in America, today is a political holiday. But let's avoid politics for the moment. Here's a few more wtfs.

"Error messages are hard," sums Ben Holzman , mock-replying "Your new puzzle games are fun, LinkedIn, but your error messages need a little work…"

0

 

Orin S. chooses wisely "These should behave like radio buttons, so… No?" I get his point, but I think the correct answer is "Yes, they are checkboxes".

1

 

Mark W. refreshes an occasionally seen issue. "Fair enough, Microsoft Office - I don't trust those guys either." Without more diagnostics it's hard to say what's going here but maybe some of you have seen this before.

2

 

ANONYMOVS chiseled out an email to us. "Maybe it really is Roman numerals? I never did find the tracking ID..."

3

 

And finally, Jonathan described this final entry as "String locationalization resource names showing," jibing that "Monday appears to be having a bad Monday." So they were.

4

 

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.

CodeSOD: The Last Last Name

Jul. 3rd, 2025 06:30 am
[syndicated profile] the_daily_wtf_feed

Posted by Remy Porter

Sometimes, you see some code which is perfectly harmless, but illustrates an incredibly dangerous person behind them. The code isn't good, but it isn't bad in any meaningful way, but it was written by a cocaine addled Pomeranian behind the controls of a bulldozer: it's full of energy, doesn't know exactly what's going on, and at some point, it's going to hit something important.

Such is the code which Román sends us.

public static function registerUser($name, $lastName, $username, ...) {
    // 100% unmodified first lines, some comments removed
    $tsCreation = new DateTime();
    $user = new User();
      
    $name = $name;
    $lastname = $lastName;
    $username = $username;
       
    $user->setUsername($username);
	$user->setLastname($lastname);
	$user->setName($name);
	// And so on.
}

This creates a user object and populates its fields. It doesn't use a meaningful constructor, which is its own problem, but that's not why we're here. We're here because for some reason the developer behind this function assigns some of the parameters to themselves. Why? I don't know, but it's clearly the result of some underlying misunderstanding of how things work.

But the real landmine is the $lastname variable- which is an entirely new variable which has slightly different capitalization from $lastName.

And you've all heard this song many times, so sing along with the chorus: "this particular pattern shows up all through the codebase," complete with inconsistent capitalization.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
[syndicated profile] raspberry_pi_feed

Posted by Lou Loxley

Inspired to set up a Code Club but not sure where to start? In this blog we hear from the amazing network of Code Club leaders and mentors, and we give you practical tips on how to take the first steps to set up your own club. 

Two young coders at a Code Club.

About Code Club

Code Club is a thriving global community of clubs where young people can develop the confidence to create with digital technologies in a fun and supportive space. Code Clubs run in schools, libraries and other community settings. We have already supported 2 million school-aged young people worldwide to make things they care about with code.

We offer free training and ongoing support for anyone who would like to set up a Code Club — you don’t need to have a background in coding and technology to get involved.

Two teachers give their tips on setting up a Code Club

“If you’re thinking of starting a Code Club, do it. The Code Club team has everything created — all the resources are available.” – Peter Hutyan, Code Club mentor, The Mease Spencer Academy, UK. 

Peter, a primary school teacher, has been running a Code Club for seven years at The Mease Spencer Academy in Derby, UK.

A man smiling.

“When I started Code Club, I didn’t know how to do Scratch”, says Peter about the block-based coding tool that lots of young learners start with. “So I made myself learn how to use Scratch and I was two to three lessons ahead of the kids. Basically I’ve done what the kids will do — I’ve read the instructions and created the code. It’s such a phenomenal experience of enriching young people’s lives, and you see the smile and sense of accomplishment on their faces. It’s the best day ever.”

Rachael Coultart is the Computer Subject Leader at St Nicholas Primary School, Stevenage, UK and has run a Code Club for over ten years.

A woman laughing.

“I think the benefits of running a Code Club for our school are that it really develops children’s collaboration skills, really develops their perseverance, their thinking skills, their independence”, Rachael says. 

“The key ingredients that I think make a Code Club successful is enthusiasm, from the adults who are there, a kind of passion to learn together and make mistakes together. I kind of think that sets the scene for the children to make mistakes as well. And I think having that freedom outside the classroom is what makes a Code Club really successful.” – Rachael Coultart, Computing Subject Leader, St Nicholas Primary School, UK

Club mentors share why they were inspired to start a club

Saad Koubeissi runs four Code Clubs in libraries in London, UK.

A man smiling.

“Code Club, for me personally, is about providing children with things I didn’t have when I was younger”, says Saad. “I went to youth clubs and stuff but it was never, like, so specific in tech, it was more, like, playing football. So Code Club, I think, by starting off early, it’s introducing children not only to identifying those skills, but also the terminologies, providing that. And being able to be part of that change for those children is welcome for me, to be honest.” 

Bob Bisland is a mentor who started his first Code Club twelve years ago after a career in technology. He now runs three clubs in Malvern, UK.

A man smiling.

“Everyone should set up a Code Club. This is such a rewarding thing to be able to do. I am sharing my passion and my knowledge with another generation of children, and I’m seeing them learn what coding is all about.”

Ready to start? Three steps to set up a Code Club

We provide everything you need to make starting a club straightforward, including hundreds of free coding projects to help you tailor your sessions to the interests of your young tech creators. Our projects are available in up to 40 languages.

  1. Choose your venue. Code Clubs are held in lots of different places, such as schools, libraries and community centres.
  2. Register your club. Complete your application to start your club. We’ll ask for a few details, e.g. the address of your club. 
  3. Start running your club. You can access our free training on how to prepare to run a Code Club. Our Code Club leader guide also includes helpful information for running your club. 

Running a Code Club is a fun and rewarding way to engage young people and help them learn valuable skills for the future. Start your Code Club journey today by finding out more about setting up a club.

The post Begin your Code Club journey: Set up a club today appeared first on Raspberry Pi Foundation.

Profile

jaq: (Default)
jaq

March 2012

S M T W T F S
    123
45678910
11121314151617
1819 2021222324
25262728293031

Style Credit

Expand Cut Tags

No cut tags