readability – Why did fonts go so wrong in Windows?

Microsoft have done a series of efforts to make the fonts look better on different screens. For instance, Microsoft invented ClearType, which was absolutely breathtaking back in 2000, and they created custom fonts such as Segoe UI which also—back then—looked like an excellent alternative to the existing fonts. I remember, a long time ago, that the default rendering in Windows looked much, much nicer than the custom one in Adobe Photoshop (running on Windows), which was always muddy/blurry/weird.

Despite their efforts, it doesn’t seem that they are doing great compared to the competition:

  1. I maintain a website where I take great care about how things look, which includes anything related to text: fonts, sizes, spacing, text rendering. As I work on Linux, I’m always surprised how the site looks ugly on Windows. It should be the same font (from Google Fonts), but at pixel level, it just doesn’t look right. Aside, Unicode characters get smashed, spacing is changed, etc. What a mess.

  2. Recently, Stack Overflow announced that the custom fonts will be replaced by the default system ones. I wasn’t at all optimistic about the change before they did the switch, but one morning, when I discovered the new version, it looked actually better than the original. More readable on Linux at least. On Android, I don’t see much of a difference (maybe because I don’t use the site as much on a smartphone). Similarly, a colleague who uses an Apple computer found that the site looks much better now.

    To my surprise, the announcement received plenty of negative comments:

    • “The fonts look truly horrific.”
    • “Oh my eyes… this font seems pixelized.”
    • “Ewww (Windows 10). Can we have the old ones back please?”
    • “Code fonts look blown out (font-weight) and fuzzy at the edges.”
    • “As a nearly 50 year old viewing the site on Windows 10, this change is terrible for my aging eyes.”

    The comments go on, and so do the upvotes of those comments. Although some don’t tell what OS are they using, many do confirm that they are Windows users.

I would expect—exactly as Stack Overflow designers expected—that the default OS font should be highly optimized, properly configured for a given device. It seems that this is the case for Apple, Linux, and Android, but absolutely not the case for Windows.

How did it go so wrong for Microsoft?

javascript – Refactor code following modular architecture for readability and maintainability

I don’t know what the title should be, but I am having very hard time to refactor my codes.

I need some insight and help.

Here is the business requirements:

An order needs to be created and processed.

Order can have different types of items and their process will be different.

There will be some base operation on order like applying coupon, or applying coins.

Here is my code, OrderController.js

const createOrder = async (req, res) => {
  const orderData = {
    zoneId: req.body.zone_id,
    combos: req.body.combos,
    couponCode: req.body.combos,
    services: req.body.services,
    isCoinsUsed: req.body.coins_used,
  };
  const userId = req.user.id;
  const notes = {};
  let cartValue = {};

  const cartItems = await OrderService.doGetCartItemsByUserId(userId);
  if (!cartItems.length) {
    throw new BadRequestError('No items in cart');
  }
  if (orderData.couponCode) {
    const userCartValue = await OrderService.doApplyCoupon({
      userId,
      cartItems,
      zoneId: orderData.couponCode,
      couponCode: orderData.couponCode,
    });
    cartValue = userCartValue;
    notes.couponCode = orderData.couponCode;
    notes.couponDiscount = cartValue.coupon_discount;
  } else {
    cartValue = calculateCartValue(cartItems);
  }
  if (orderData.isCoinsUsed) {
    const coins = await WalletService.getWalletBalance({ userId });
    notes.coinsUsed = coins > cartValue.total ? cartValue.total : coins;
  }
  // create order and generate receipt
  const order = await OrderService.doCreateOrder({
    notes,
    userId,
    cartItems,
    cartValue,
    combos: orderData.combos,
    services: orderData.services,
  });
  if (orderData.services
    && orderData.services.length) {
    order.bookings = await RequestService.doCreateServiceRequest({
      userId,
      orderId: order.id,
      requestedServices: orderData.services,
    });
  }
  return res.status(200).send(order);
};

OrderServic.js

const doCreateOrder = async ({
  notes,
  userId,
  createdBy,
  cartItems,
  updatedBy,
  userDevice,
}) => {
  const { couponDiscount, coinsUsed } = notes;
  let rzOrder = {};
  const result = await sequelize.transaction(async (t) => {
    const totalItemAmount = await doGetTotalItemAmount(cartItems);
    const totalDueAmount = totalItemAmount - (couponDiscount || 0 + coinsUsed || 0);
    if (totalDueAmount > 0) {
      rzOrder = await RazorpayService.createRzOrder({
        notes,
        userId,
        amount: totalDueAmount,
      });
    }
    const order = await Order.create(
      {
        user_id: userId,
        status: ORDER_CREATED,
        device_type: userDevice,
        coins_used: coinsUsed || 0,
        notes: JSON.stringify(notes),
        coupon_discount: couponDiscount || 0,
        order_number: `OD-${genRandomString(userId)}`,
        created_by: createdBy,
        updated_by: updatedBy,
        invoices: ({
          razorpay_order: rzOrder.id,
          total_amount: totalItemAmount,
          total_due_amount: totalDueAmount,
        }),
      },
      {
        include: {
          model: Invoice,
          as: 'invoices',
        },
        transaction: t,
      },
    );

    const orderData = order.toJSON();
    const invoiceId = orderData.invoices(0).id;
    cartItems.forEach((carItem) => {
      carItem.invoice_id = invoiceId;
      carItem.order_id = order.id;
    });
    const orderItems = await OrderItem.bulkCreate(cartItems, { transaction: t });
    const orderItemInvoices = JSON.parse(JSON.stringify(orderItems)).map(
      (orderItem) => ({
        customer_order_item_id: orderItem.id,
        invoice_id: invoiceId,
      }),
    );
    const invoiceItems = await OrderItemInvoice.bulkCreate(orderItemInvoices, { transaction: t });
    orderData.orderItems = orderItems;
    orderData.invoiceItems = invoiceItems;
    if (notes.coins_used) {
      const walletDetail = await WalletService.deductFromWallet({
        userId,
        createdBy,
        updatedBy,
        transaction: t,
        orderId: order.id,
        amount: order.coins_used,
        transactionComment: `Debited against order ${order.order_number}`,
      });
      orderData.walletDetail = walletDetail;
    }
    if (notes.couponCode) {
      await CouponService.doCreateCouponUse({
        userId,
        createdBy,
        updatedBy,
        transaction: t,
        orderId: order.id,
        couponCode: notes.couponCode,
        couponDiscount: notes.couponDiscount,
      });
    }
    return orderData;
  });
  return result;
};

As you can see a lot of things going on here, and I am not able to find any easy way to refactor it.

I always face this problem. How can I make it better and readable? and separate it in simple modules?

design patterns – Refactor code following modular architecture for readability and maintainability

I don’t know what the title should be, but I am having very hard time to refactor my codes.

I need some insight and help.

Here is the business requirements:

An order needs to be created and processed.

Order can have different types of items and their process will be different.

There will be some base operation on order like applying coupon, or applying coins.

Here is my code, OrderController.js

const createOrder = async (req, res) => {
  const orderData = {
    zoneId: req.body.zone_id,
    combos: req.body.combos,
    couponCode: req.body.combos,
    services: req.body.services,
    isCoinsUsed: req.body.coins_used,
  };
  const userId = req.user.id;
  const notes = {};
  let cartValue = {};

  const cartItems = await OrderService.doGetCartItemsByUserId(userId);
  if (!cartItems.length) {
    throw new BadRequestError('No items in cart');
  }
  if (orderData.couponCode) {
    const userCartValue = await OrderService.doApplyCoupon({
      userId,
      cartItems,
      zoneId: orderData.couponCode,
      couponCode: orderData.couponCode,
    });
    cartValue = userCartValue;
    notes.couponCode = orderData.couponCode;
    notes.couponDiscount = cartValue.coupon_discount;
  } else {
    cartValue = calculateCartValue(cartItems);
  }
  if (orderData.isCoinsUsed) {
    const coins = await WalletService.getWalletBalance({ userId });
    notes.coinsUsed = coins > cartValue.total ? cartValue.total : coins;
  }
  // create order and generate receipt
  const order = await OrderService.doCreateOrder({
    notes,
    userId,
    cartItems,
    cartValue,
    combos: orderData.combos,
    services: orderData.services,
  });
  if (orderData.services
    && orderData.services.length) {
    order.bookings = await RequestService.doCreateServiceRequest({
      userId,
      orderId: order.id,
      requestedServices: orderData.services,
    });
  }
  return res.status(200).send(order);
};

OrderServic.js

const doCreateOrder = async ({
  notes,
  userId,
  createdBy,
  cartItems,
  updatedBy,
  userDevice,
}) => {
  const { couponDiscount, coinsUsed } = notes;
  let rzOrder = {};
  const result = await sequelize.transaction(async (t) => {
    const totalItemAmount = await doGetTotalItemAmount(cartItems);
    const totalDueAmount = totalItemAmount - (couponDiscount || 0 + coinsUsed || 0);
    if (totalDueAmount > 0) {
      rzOrder = await RazorpayService.createRzOrder({
        notes,
        userId,
        amount: totalDueAmount,
      });
    }
    const order = await Order.create(
      {
        user_id: userId,
        status: ORDER_CREATED,
        device_type: userDevice,
        coins_used: coinsUsed || 0,
        notes: JSON.stringify(notes),
        coupon_discount: couponDiscount || 0,
        order_number: `OD-${genRandomString(userId)}`,
        created_by: createdBy,
        updated_by: updatedBy,
        invoices: ({
          razorpay_order: rzOrder.id,
          total_amount: totalItemAmount,
          total_due_amount: totalDueAmount,
        }),
      },
      {
        include: {
          model: Invoice,
          as: 'invoices',
        },
        transaction: t,
      },
    );

    const orderData = order.toJSON();
    const invoiceId = orderData.invoices(0).id;
    cartItems.forEach((carItem) => {
      carItem.invoice_id = invoiceId;
      carItem.order_id = order.id;
    });
    const orderItems = await OrderItem.bulkCreate(cartItems, { transaction: t });
    const orderItemInvoices = JSON.parse(JSON.stringify(orderItems)).map(
      (orderItem) => ({
        customer_order_item_id: orderItem.id,
        invoice_id: invoiceId,
      }),
    );
    const invoiceItems = await OrderItemInvoice.bulkCreate(orderItemInvoices, { transaction: t });
    orderData.orderItems = orderItems;
    orderData.invoiceItems = invoiceItems;
    if (notes.coins_used) {
      const walletDetail = await WalletService.deductFromWallet({
        userId,
        createdBy,
        updatedBy,
        transaction: t,
        orderId: order.id,
        amount: order.coins_used,
        transactionComment: `Debited against order ${order.order_number}`,
      });
      orderData.walletDetail = walletDetail;
    }
    if (notes.couponCode) {
      await CouponService.doCreateCouponUse({
        userId,
        createdBy,
        updatedBy,
        transaction: t,
        orderId: order.id,
        couponCode: notes.couponCode,
        couponDiscount: notes.couponDiscount,
      });
    }
    return orderData;
  });
  return result;
};

As you can see a lot of things going on here, and I am not able to find any easy way to refactor it.

I always face this problem. How can I make it better and readable? and separate it in simple modules?

readability – reading mathematical formula’s in pdf with matlab is inconsistent, how to generalize this?

I’m trying to extract certain pieces of text (the 4.50% and the 22.50% in picture 1) from a pdf file with matlab. To do so I use the pdfRead function. To get the text as generic as possible I remove enters, double spaces, tabs and indents and make all text uppercase. In reading the file, I run into the following problem:

  • some text in the file seems to be in math mode (see picture 1 and pay special attention to the two cases of “Notional Amount”) :

File I try to read with math mode in different places.

  • It turns out this math mode is not consistent when reading it with pdfRead (see picture 2 and pay special attention to the two cases of “Notional Amount” (For readability I chose to show the file before removing enters, double spaces etc. however the problem is the same)).
  • The spaces within the word “notional amount” here are in a different spot for every pdf file, this results in the fact that I cannot use 1 matlab code for multiple pdf files (I do need that).

Problem when reading in Matlab

  • Besides this when copy pasting the part into my command window it appears different than it appears in the text (see picture 3)

Difficulty with copy paste

My question consists of multiple questions:

  1. Why doesn’t the text appear as text and how can I make it appear as text?
  2. How can I make this part generic such that I can read multiple pdf files with the same code?

Solutions I tried:

  • Removing all spaces
  • Saving it as a txt file and try to change font (the formula part didn’t change)
  • Use Python to try to adjust the file

c# – Use local or nested function for readability?

I always thought that local functions were created to avoid writing
multiple times the same code

No. That’s a misconception, outdated since the 1970s, and I’m happy that we have since learned a few things.

Refactoring code chunks into functions is an example of following the guideline

We introduce classes/methods/functions etc. to create the language we want to be using to express our solution.

So, this refactoring certainly is the right thing to do, if the language thus introduced better expresses the solution steps.

But, is the following

private void CopyOneFileToOtherInSomeDirectory(string path, string filename, string outputFilename)
{
    (...)
    var readedText = Read();
    Write(readedText);
}

really the way you want to express the steps of copying a file?

E.g., is Read() a good abstraction vocabulary for what it does? I don’t think so. It lacks clarity, as you don’t see where it reads from (filename in path), a very important information. So, to understand what it does, you still have to look into the function, and that means it’s less readable (IMHO) than the original non-refactored version.

Is AppendPathSeparator(path) part of a good language for expressing the file-copy task? It’s a helper dealing with one aspect of path syntax, necessary only in the context of combining a directory name and a file name. What you really want to do there is this combining of directory and file, and the aspect that you might or might not need an additional slash should abstracted deep into some lower level of language.

If I were to create the language for the file copying function, I’d prefer something like:

private void CopyOneFileToOtherInSomeDirectory(string path, string filename, string outputFilename)
{
    var readedText = Read(Combine(path, filename));
    Write(readedText, (Combine(path, outputFilename));
    (...)
}

Some general ideas:

  • Language should be clear: when reading it, you should get a good idea of what happens there. That’s what I missed in the Read() and Write(text) words.
  • Language should use a consistent abstraction layer. If you create abstract vocabulary for some aspects of pathname syntax, you should cover all aspects.
  • Language should be free of redundancy. Having multiple synonyms that express more or less the same concept is nice in literature, but not in software.
  • Language should be unambiguous: a word like Read() should mean the same thing wherever you encounter it.

When following these guidelines, the ExtractFunction refactoring greatly improves code quality.

Regarding performance: you can safely ignore the tiny performance impact of this refactoring until you really run into a performance problem.

Optimize for performance only if it is necessary. That can’t be over-emphasized.

And all real-world performance problems I ever experienced came from other sources, never ever was it an additional level of function calls.

readability – Which Code Lines Are More Readable?

Although I am having doubts to asking this question, I decided to ask. I have two different code blocks and two different preferences for each. Please decide one of it and share your reasons.

IF RETURN / RETURN OR IF RETURN / ELSE RETURN

OPTION 1

if(statement){
   //do things
   RETURN abc;
}
else {
   RETURN xyz;
}

OPTION 2

if(statement){
   //do things
   RETURN abc;
}

RETURN xyz;

According to me, first option is more readible and easier to understand. I know that if statement is correct, else section is completely ignored. However if we use option 2, we should consider last return too. What do you think?

MULTIPLE IF BLOCKS ONE BY ONE OR SINGLE, BULKY STATEMENTS

const isValidFirstName = (firstName) => (
  .
  .
  .
  //return true or false
);

const isValidLastName = (lastName) => (
  .
  .
  .
  //return true or false
)

const isValidContactDetail = (contactDetail) => (
  .
  .
  .
  //return true or false
)

OPTION 1

const formValidation = ({ firstName, lastName, contactDetail, email, phoneNumber, message }) => {
  if (!isValidFirstName(firstName)) {
    return false;
  }

  if (!isValidLastName(lastName)) {
    return false;
  }

  if (!isValidContactDetail(contactDetail)) {
    return false;
  }
  .
  .
  .
  //3 or 4 more statements
  return true;
}

OPTION 2

const formValidation = ({ firstName, lastName, contactDetail, email, phoneNumber, message }) => {
      if (!isValidFirstName(firstName) && 
          !isValidLastName(lastName) &&
          !isValidContactDetail(contactDetail) &&
          . &&
          . &&
          . &&
          //3 4 more statements
      ) {
        return false;
      }
      return true;
}

I think first option is more readable because we can distinct which statements for which and easier to debug if anything unexpected happens. It is significantly causes more code lines but I am not sure which one is better.

PS: I know that all situations are doing the same thing and no difference in compilation & performance.

Thanks a lot.

Can I rate a block of texts based on its typography for its readability or legibility?

Can I rate typography? Based on the various components which make up a block of texts like- X height, font-weight, Line space, margin, and such other values – Can I find threshold values below which readability/ legibility suffers? I have gone through several research papers but couldn’t find specific ones.

programming practices – Padding variable declarations with inline comments for better readability

I declared some variables, at the beggining of a java method, like this:

final Set<Scheduled>/*****/ roots/***********/ = new HashSet();
final Set<Scheduled>/*****/ alreadySeen/*****/ = new HashSet();
final Queue<Scheduled>/***/ junctionQueue/***/ = new LinkedList(junctions);

Now I’m struggling to find a good reason not to do this! Since improved readability.
Should one do this? to help fellow coders to understand the code easier.

Some IDEs would remove consecutive blank spaces, so isn’t an option.

There is no SE for coding style questions. Yet, whatever gets upvoted, will show some consensus.

javascript – Readability vs. maintainability: nested functions

The nested function is not bad (depending on the situation). Of course, they bring more complexity and reduces extensibility. But in some cases, you wish to bundle some function that works with the main function output (well, it’s not very different from the class).

Of course you should return object instead of the list for the usage convenience:

const myFunction = ({foo, bar}) => {
  return {
    function1() {
        return foo + bar
    },
    function2() {
        return foo * bar;
    }
  }
}
myFunction().function1()

To sum up, this design can simplify usage in some cases. However, the worst thing about this pattern is that these functions are not extendible and you can’t use partial functionality (like using only function1). In most cases, I recommend avoiding this unless you are writing a library/helper function and which to simplify usage by attaching other chain function to the main output (fetch is a good example).

Option 2

Regarding the second option, it works fine as long as your function is not too complex and you don’t have too many parameters. You can partially solve the issue with a lot of parameters using TypeScript (because you can statically describe them).

However, if possible I recommend changing logic a bit. Instead of requiring all parameters why don’t you require the output of functions? Then you can have multiple functions which return different output + you can also write your own implementation for one part. This option opens a way for unlimited possibilities.

Example:

const myFunction = ({foo, bar}) => {
    return (
        foo,
        bar
    )
}

myFunction({
    foo: function1(),
    bar: function1(),
})

// You can "extend" this function:
myFunction({
    foo: function1(),
    bar: myCustomFunction(),
})

readability – What is a good choice of letters for serial numbers?

When creating serial numbers, one could use only numbers, 09. This causes serial numbers to be quite long. To save space, one could also user letters AZ, resulting in shorter numbers, by a factor of 1.56 (log 36 / log 10). But this can cause trouble reading those serial numbers, since 0 and O are quite similar. Also l and 1, and mayby I and 1, or even J and 1.

So a first approximation seems to be to use the digits 0123456789ABCDEFGHKMNPQRSTUVWXYZ for serial numbers. That is 32 digits and hence serial numbers are still 1.51 times shorter than in base-10.

Is there any well-known best practice for issuing serial numbers?