Author: Naveen

  • Long term energy storage solution

    I always thought any generated energy can be stored only in batteries.

    The most efficient energy storage technology may be as close as the nearest hill, according to former Energy Secretary Steven Chu, and almost as old.

    “It turns out the most efficient energy storage is you take that electricity and you pump water up a hill,” Chu said Tuesday at the Stanford University Global Energy Forum.

    When electricity is needed, you let the water flow down, spinning generators along the way. Pumped hydro can meet demand for seasonal storage instead of the four hours typical of lithium-ion batteries.

    Steven Chu: Long-Term Energy Storage Solution Has Been Here All Along

    So, you can have a hydro power plant generate electricity with water flowing down and use any excess electricity to pump water back up the reservoir to store the excess energy. Neat!

  • Creating disposable email address on Gmail, with expiration date

    I knew we could create disposable email address on Gmail by appending + to username and adding random characters after that, but didn’t know we could add expiration date to them.

    Let’s say your temporary email address is amit@gmail.com. A website form requires your email address so you can put amit+mmdd@gmail.com in the sign-up field where mmdd is the month and date till when that disposable email will stay valid.

    For instance, if you specify the email address as amit+0623@gmail.com – that alias will be valid until June 23 and any emails sent to that alias after that date are ignored else they are forwarded to your main Gmail address. You can only specify the year in your temporary email amit+12312020@gmail.com in mmddyyyy format.

    How to Create a Disposable Email Address with Gmail

  • How Cooper Black became pop culture’s favorite font

    Never noticed it, but Cooper Black is actually everywhere. Even my daughter’s alphabet letter set is in Cooper Black!

  • The goat is gone

    Considering the raging COVID-19 pandemic, job losses and all around negativity, why are the markets going up? Well, the goat is gone.

    In a certain village, there is a very large and poor family who are living in a cramped room. One day, the head of the family goes to a wise old grandmother of the village and asks for some advice. “There are 12 of us in this tiny room,” he says. “It’s so dirty and cramped, everyone is always fighting, the children are crying, and there is no place for anyone to even lie down. What should I do?”

    The wise old woman says, “Keep your goat also in the room.” The man says, “Are you mad? The goat will make things worse.”

    “Just do it”, says the old woman. The man comes back a few days later and tells her that now, life is absolute hell. “The goat is smelly and there are droppings all over and it kicks everyone and bleats loudly all the time.” The old woman says “OK, fine, if it’s so bad then keep the goat outside”. Now the man comes back after a few days, looking pleased and happy. “It’s wonderful, he says. It’s just the 12 of us and we have the whole room to ourselves! No goat!”

    The goat is gone

  • Animations in Office UI Fabric

    Working on an assignment and rummaging through Google search results I ran into this page. Apparently, Office UI Fabric supports animation. But the documentation does not list out any details as to what classes to use, neither are there any examples. More search and I find this issue having similar complaint as mine. The issue also lists a sample code using CSS-in-JS to implement animation. Lets take a look.

    First lets import animation modules from Office UI Fabric.

    import { AnimationStyles, AnimationClassNames, AnimationVariables } from 'office-ui-fabric-react/lib/Styling';

    Lets take a look at what each modules does.

    AnimationStyles

    This module contains all the standard Office UI Fabric animations as JSON objects with predefined keyframes. Below are the styles we can use.

    slideRightIn10
    slideRightIn20
    slideRightIn40
    slideRightIn400
    slideLeftIn10
    slideLeftIn20
    slideLeftIn40
    slideLeftIn400
    slideUpIn10
    slideUpIn20
    slideDownIn10
    slideDownIn20
    slideRightOut10
    slideRightOut20
    slideRightOut40
    slideRightOut400
    slideLeftOut10
    slideLeftOut20
    slideLeftOut40
    slideLeftOut400
    slideUpOut10
    slideUpOut20
    slideDownOut10
    slideDownOut20
    scaleUpIn100
    scaleDownIn100
    scaleUpOut103
    scaleDownOut98
    fadeIn100
    fadeIn200
    fadeIn400
    fadeIn500
    fadeOut100
    fadeOut200
    fadeOut400
    fadeOut500
    rotate90deg
    rotateN90deg

    To use AnimationStyles you use the CSS-in-JS approach with the JavaScript spread operator.

    const btnStyleSlideIn: IButtonStyles = {
        root: {
            ...AnimationStyles.slideLeftIn400
        }
    };

    Below is the sample React code implementation.

    public render(): React.ReactElement {
        const btnStyleSlideIn: IButtonStyles = {
            root: {
                ...AnimationStyles.slideLeftIn400
            }
        };
        return (<>
            <PrimaryButton text="Animate"
                onClick={(_) => {
                    this.setState({
                        enableAnimation: true
                    }, () => {
                        setTimeout(() => {
                            this.setState({
                                enableAnimation: false
                            });
                        }, 2000)
                    });
                }}
                disabled={this.state.enableAnimation} />
            <Button text="I am sliding in to left"
                iconProps={{ iconName: 'ChevronLeft' }}
                styles={this.state.enableAnimation ? btnStyleSlideIn : {}} />
        </>);
    }

    AnimationClassNames

    This module contains all the standard Office UI Fabric animation class names. It is similar to AnimationStyles but it just gives you class names rather than the JSON object. Below is the sample React code implementation.

    public render(): React.ReactElement {
        return (<>
            <PrimaryButton text="Animate"
                onClick={(_) => {
                    this.setState({
                        enableAnimation: true
                    }, () => {
                        setTimeout(() => {
                            this.setState({
                                enableAnimation: false
                            });
                        }, 2000)
                    });
                }}
                disabled={this.state.enableAnimation} />
            <Button text="I am sliding in to left, using CSS class"
                iconProps={{ iconName: 'ChevronLeft' }}
                className={this.state.enableAnimation ? AnimationClassNames.slideLeftIn400 : ""} />
        </>);
    }

    AnimationVariables

    This module exports duration values and easing functions which can be used in custom animations. You can use these values in your animations. If you log it to browser console you should see something similar to below output.

    {
        durationValue1: "0.167s",
        durationValue2: "0.267s",
        durationValue3: "0.367s",
        durationValue4: "0.467s",
        easeFunction1: "cubic-bezier(.1,.9,.2,1)",
        easeFunction2: "cubic-bezier(.1,.25,.75,.9)"
    }

    Below is a sample React code implementation.

    public render(): React.ReactElement {
        const kf: string = keyframes({
            "12.5%": { left: -5 },
            "25%": { left: 5 },
            "37.5%": { left: -2.5 },
            "50%": { left: 2.5 },
            "62.5%": { left: -1 },
            "75%": { left: 1 }
        });
        
        const btnStyleShakeIt: IButtonStyles = {
            root: {
                animationDuration: AnimationVariables.durationValue1, // Use Office UI Fabric animation duration
                animationName: kf
            }
        };
    
        return (<>
            <PrimaryButton text="Animate"
                onClick={(_) => {
                    this.setState({
                        enableAnimation: true
                    }, () => {
                        setTimeout(() => {
                            this.setState({
                                enableAnimation: false
                            });
                        }, 2000)
                    });
                }}
                disabled={this.state.enableAnimation} />
            <Button text="Shake it!"
                styles={this.state.enableAnimation ? btnStyleShakeIt : {}} />
        </>);
    }

  • Second-Order Thinking

    First-order thinking is fast and easy. It happens when we look for something that only solves the immediate problem without considering the consequences. For example, you can think of this as I’m hungry so let’s eat a chocolate bar.

    Second-order thinking is more deliberate. It is thinking in terms of interactions and time, understanding that despite our intentions our interventions often cause harm. Second order thinkers ask themselves the question “And then what?” This means thinking about the consequences of repeatedly eating a chocolate bar when you are hungry and using that to inform your decision. If you do this you’re more likely to eat something healthy.

    First-level thinking looks similar. Everyone reaches the same conclusions. This is where things get interesting. The road to out-thinking people can’t come from first-order thinking. It must come from second-order thinking. Extraordinary performance comes from seeing things that other people can’t see.

    Second-Order Thinking: What Smart People Use to Outperform

    A more succinct version by the same author.

    Second-order thinking is the practice of not just considering the consequences of our decisions but also the consequences of those consequences. Everyone can manage first-order thinking, which is just considering the immediate anticipated result of an action. It’s simple and quick, usually requiring little effort. By comparison, second-order thinking is more complex and time-consuming. The fact that it is difficult and unusual is what makes the ability to do it such a powerful advantage.

    Chesterton’s Fence: A Lesson in Second Order Thinking

  • Why we fail to prepare for disasters

    Considering the current COVID-19 pandemic, one of the best things I have read on why we failed to get a grasp on this.

    Part of the problem may simply be that we get our cues from others. In a famous experiment conducted in the late 1960s, the psychologists Bibb Latané and John Darley pumped smoke into a room in which their subjects were filling in a questionnaire. When the subject was sitting alone, he or she tended to note the smoke and calmly leave to report it. When subjects were in a group of three, they were much less likely to react: each person remained passive, reassured by the passivity of the others.

    As the new coronavirus spread, social cues influenced our behaviour in a similar way. Harrowing reports from China made little impact, even when it became clear that the virus had gone global. We could see the metaphorical smoke pouring out of the ventilation shaft, and yet we could also see our fellow citizens acting as though nothing was wrong: no stockpiling, no self-distancing, no Wuhan-shake greetings. Then, when the social cues finally came, we all changed our behaviour at once. At that moment, not a roll of toilet paper was to be found.

    Why we fail to prepare for disasters

    But at the end it gets scary, really scary.

    Because Covid-19 has spread much faster than HIV and is more dangerous than the flu, it is easy to imagine that this is as bad as it is possible to get. It isn’t. Perhaps this pandemic, like the financial crisis, is a challenge that should make us think laterally, applying the lessons we learn to other dangers, from bioterrorism to climate change. Or perhaps the threat really is a perfectly predictable surprise: another virus, just like this one, but worse. Imagine an illness as contagious as measles and as virulent as Ebola, a disease that disproportionately kills children rather than the elderly.

    What if we’re thinking about this the wrong way? What if instead of seeing Sars as the warning for Covid-19, we should see Covid-19 itself as the warning?

    Next time, will we be better prepared?

    Why we fail to prepare for disasters

    If COVID-19 is a warning, then what will the actual disaster look like?

  • Testing SPFx web part on Modern page – not on workbench

    For a long time I have been developing and testing my SPFx web part on workbench.aspx, which is a terrible option considering you only have limited screen space and you don’t get to see how your web part will look like once it is added to the page. Well, there is a way to test and debug your web part on Modern page.

    First, lets create sppkg package to deploy. For that, run the below commands.

    1. gulp clean
    2. gulp bundle
    3. gulp package-solution

    Note that I am not using the --ship option while running the bundle and package-solution tasks. This will give you a warning – [package-solution] This is not a production build (--ship or --production), therefore the "includeClientSideAssets" setting will be ignored. That’s what we want.

    Second, deploy your generated sppkg package to App Catalog and add web part to your page. When you load the page it will give error.

    This is because our code was not added to sppkg package as we did not use the --ship option.

    Third and final step, run gulp serve command and view the page. You can now test and debug the web part on the page.

  • TextEdit on Mac without formatting

    By default TextEdit shows rich text formatting options and saves file in RTF format. If you are looking for no-frills plain text editor, go to Format > Make Plain Text or press command + shift + T. The menu and key are essentially a toggle which switch between rich text and plain text. To make the plain text permanent go to TextEdit > Preferences… and select Plain text under the Format section.

  • Get count of items/files in list/document library in SharePoint Online with SPFx

    In SharePoint Online, when we view Site Contents, internally a call is made to the end point /_api/web/AppTiles to get the count of items/files in list/document library that the current site collection has. We can call this API in SPFx webpart to get these details. Below is the sample code.

    import { SPHttpClient, SPHttpClientResponse, SPHttpClientConfiguration } from '@microsoft/sp-http';
    
    this.context.spHttpClient.get(`${this.context.pageContext.web.absoluteUrl}/_api/web/AppTiles`, SPHttpClient.configurations.v1)
      .then((response: SPHttpClientResponse) => {
        response.json()
          .then((responseJSON: any) => {
            console.log(responseJSON); // Gets all the list and document library details in JSON
          })
          .catch(error => {
            console.log(error);
          });
      })
      .catch(error => {
        console.log(error);
      });

    this.context refers to WebPartContext in the BaseClientSideWebPart class. The output will looks something like below JSON snippet. There is a lot of detail here which we can filter using $select. The attributes we require are Title and ChildCount.

    {
        "@odata.context": "https://mysite.sharepoint.com/sites/mysitecollection/_api/$metadata#AppTiles",
        "value": [
          {
            "@odata.type": "#SP.AppTile",
            "@odata.id": "https://mysite.sharepoint.com/sites/mysitecollection/_api/SP.AppTile0aab34a5-8bb4-4d5e-bac0-90841a08dd34",
            "@odata.editLink": "SP.AppTile0aab34a5-8bb4-4d5e-bac0-90841a08dd34",
            "AppId": "58de69fc-9e3f-4375-af44-205eeb452366",
            "AppPrincipalId": "",
            "AppSource": 0,
            "AppStatus": 4,
            "AppType": 0,
            "AssetId": "0;00bfea23-e717-4e80-bb17-d0c71b360101;101;",
            "BaseTemplate": 101,
            "ChildCount": 5,
            "ContentMarket": "",
            "CustomSettingsUrl": "",
            "Description": "",
            "IsCorporateCatalogSite": false,
            "LastModified": "4/26/2020 4:16 AM",
            "LastModifiedDate": "2020-04-26T11:16:27Z",
            "ProductId": "00cfea20-e900-4e80-aa17-d0c71b360101",
            "Target": "/sites/mysitecollection/Shared Documents/Forms/AllItems.aspx",
            "Thumbnail": "/_layouts/15/images/ltdl.png?rev=47",
            "Title": "Documents",
            "Version": "4"
          },
          ...
        ]
      }