March 5, 2020
Wow! Soooo long since my last blog post. Since then I have been 'hiding in my cave' doing lots of learning. I am proud of all the things I had to learn to publish the latest GSuite Add-on: Automagical Forms.
Here is a non-exhaustive list of things I was learning (enough to get things to work, don't ask me to explain why they work ;) while not blogging since October:
Node.js
Google Cloud Platform
Cloud Functions
Cloud APIs
AWS
S3 APIs
Lamda
DynamoDB
Encryption
Hashing
All about PDFs
looking at PDF binary, decoding, encoding, way too much PDF stuff
Machine Learning
Training Models
Testing AWS vs GCP platforms for modeling
Artificial Intelligence (who knew that all those Graph Theory classes I took in Graduate School would have an application one day!)
GSuite Add-on
Card UI (all that HTML I learned for UI in my Add-ons is no longer valid :( )
New APIs and code flows
Manifests
Typescript
Functional programming
Why some ES6 code won't work in Google Apps Script
New GSuite Marketplace publishing process
Developing for GDPR, FERPA, COPPA, and HIPPA compliance
I plan on blogging about the GSuite Marketplace publishing process and hopefully some of the other topics in depth, but I have a few other Add-ons to put the finishing touches and get them out publicly in the coming week(s).
March 5, 2020
Wow! Soooo long since my last blog post. Since then I have been 'hiding in my cave' doing lots of learning. I am proud of all the things I had to learn to publish the latest GSuite Add-on: Automagical Forms.
Here is a non-exhaustive list of things I was learning (enough to get things to work, don't ask me to explain why they work ;) while not blogging since October:
Node.js
Google Cloud Platform
Cloud Functions
Cloud APIs
AWS
S3 APIs
Lamda
DynamoDB
Encryption
Hashing
All about PDFs
looking at PDF binary, decoding, encoding, way too much PDF stuff
Machine Learning
Training Models
Testing AWS vs GCP platforms for modeling
Artificial Intelligence (who knew that all those Graph Theory classes I took in Graduate School would have an application one day!)
GSuite Add-on
Card UI (all that HTML I learned for UI in my Add-ons is no longer valid :( )
New APIs and code flows
Manifests
Typescript
Functional programming
Why some ES6 code won't work in Google Apps Script
New GSuite Marketplace publishing process
Developing for GDPR, FERPA, COPPA, and HIPPA compliance
I plan on blogging about the GSuite Marketplace publishing process and hopefully some of the other topics in depth, but I have a few other Add-ons to put the finishing touches and get them out publicly in the coming week(s).
October 22, 2019
Wow, I needed to put another blog post after this one two weeks ago. I have an exciting release coming soon that I want to blog about along with the development process, but first a nostalgic one inspired by the final episode of the podcast Startup.
That episode was the final episode and detailed the sale of Gimlet to Spotify. The final season of 3 episodes detailed that process and it was cool to get there after starting to listen to all the episodes a few months ago. The biggest thing that I personally took away from these was reliving the process of me selling g(Math).
Quick background: For those that don't know, I got into this developer thing sorta by accident. I developed g(Math), a Google Add-on for the students in my class as I was teaching math as a full-time teacher. It grew over the course of 2 years and had millions of users. I couldn't handle teaching full-time and supporting g(Math) so I chose the path that inspired me the most. That was going to be pursuing g(Math) as a full-time gig. Oh yeah, I was also the only one bringing in income as my wife was still staying at home with our 2 year old daughter.
So not only was I going to change careers to pursue something I had only been doing on the side for a few years, I was doing it with no financial safety net. We were living in Chile and just moved there about 8 months before from Singapore. Moving internationally is not cheap. We were going to have to move again from Chile...
<cue the voice in my head trying to be responsible>So....you are going to give up all guaranteed income, move to your 3rd country in less than a year, with a 2 year old. Oh yeah, you don't even have any experience in this field and there are really no examples of Add-ons being monetized....not the best idea </end cue>
As I was listening to Alex and Nazanin talk about the pros and cons of selling Gimlet, I flashed back to those days.
October 9, 2019
tldr; Thank you Kim and thank you Jen! Give ShukesAndGiff a go! Creating is hard. Know your core beliefs and stick to them.
Storytime.
This one might be a long one and might turn into more of a rant...but I feel it is important to those who want to be creators to see what goes on in my mind as I develop products.
<preamble>
If you don't know me, people would generally describe me as a nice guy. I have always struggled with this idea of 'being nice'. For me the line on 'being nice' and 'being walked on or taken advantage of' can be hard to discern. It is this duality between innocence and naivety is a struggle that 42 years of programming (OK, probably not 42 years but I don't know when I would have started so by default went with my age) is hard to peel away.
At my core I am inspired and drawn towards innocence. I think of innocence as being overwhelmed by the awesomeness that life has to offer. Being shown something new for the first time is so amazing and awe-inspiring. I love the wonder in my daughters eyes as she learns something new or sees something for the first time. I love traveling and experiencing a different culture and opening a new perspective. The sunrise that changes daily out my backdoor leaves me in awe. I love the elegance of a new solution method to a math problem I have taught for 10 years.
This struggle can impact my decisions or weigh heavily on my decision-making process.
</preamble>
<rant>
So about 5 years ago I made a thing called FormRecycler. In my math class I used a hybrid SBG method where students could continue to take quizzes on a certain topic. I had a set of problems that I generated with g(Math) to be the same level and autograded them with Google Forms. I would want to reuse questions and there was no native functioning in Forms to do that. So I built one. Was I the first person with the idea that this functionality was needed? Probably not. Andrew Stillman and I chatted about the functionality back in the fall of 2014 and even chatted with the Google Forms PM about it then. Nothing came about and I needed the functionality so I spent the time to clean up the code and publish FormRecycler. I published FormRecycler back on December 11, 2014. The time required to publish an Add-on can be significant. There are stringent rules that you need to abide by. Additionally once an Add-on is published it will get used (ideally) and need to be supported. That takes time as well. As you can tell by the screenshot from my Developer Dashboard, it is on version 48. That doesn't mean I have changed the code 48 times, that is the amount of times I have published an update. Some updates are just a few lines of code. Some updates were massive, like the licensing system I implemented and published back on April 1, 2019. I probably spent a couple hundred hours on my weekends and holidays to implement that code. I had to learn a bunch of new stuff and leveled up my coding a lot. I spent a lot of my free time away from my family too.
What did that licensing do? Well it restricted the usage of FormRecycler, allowing users to only recycle 50 questions per week for free. For the previous 4 years and change I had not been charging anything for its use. I spent a lot of initial time getting it published back in 2014. I spent time supporting it for the next few years. I sold g(Math) in 2016 and didn't really focus on my other Add-ons as I was fully focused on getting g(Math) turned into EquatIO and more professional. Around June 2018 Google updated the restrictions for Add-ons and I was notified that my Add-ons (FormRecycler and FormCreator) would be not working as I needed to verify the Oauth. I hadn't paid much attention to them beyond small bug fixes.
I was surprised by 2 things:
1. There were over 100,000 people who installed both of them (almost 500,000 now for FormRecycler and FormCreator got reset on a glitch in updating the Oauth Verification in the GSuite Marketplace).
2. That a better solution did not exist natively.
I had always figured that Google would eventually add the functionality natively. Every year at ISTE I would chat with people at Google and figured this was the year that FormRecycler would become obsolete.
Since that still hadn't happened. I spent the time to update my Add-ons with the Oauth verification and enable people to keep using them. After ISTE in late June 2018 and more conversations with the Forms team, my takeaway was still that there was nothing that was going to be implemented natively (not that they have an obligation to share their roadmap with me anyway).
So I decided that there were a bunch of people who found FormRecycler useful and since there were some improvements in Google Forms, mainly with the ability to do Quizzes. (Which is based off another successful Add-on, Flubaroo...). I decided to spend the time to improve FormRecycler and at the same time implement a licensing system. I didn't want to restrict the feature usage of FormRecycler and also wanted to 'still be nice'.
This is the part that I struggle with. So I had a core group of people who were using FormRecycler for years. It was integral to their teaching workflow. As teachers, my wife and I spent so much money out of our own pockets buying resources we used in the classroom. I didn't want to penalize teachers who wanted to continue using FormRecycler, but at the same time I want to value my own time. That was the internal struggle. In the end I chose 50 questions a week for free as this would impact a minority of my users. If I was a 'better businessperson' I probably would have gone for a lower quota to impact more people. The impact of this quota in April was the workflow of the user was impacted if they reached it. This meant they needed to purchase a license for $24/year or stop using FormRecycler that week. I felt like the timesaving was worth the money they would spend (or $2/month) but I also understand teacher budgets are tight and it was most likely coming out of their own pocket.
There were some nasty emails and feedback I got as a result. That was hard. They said I wasn't nice and how dare I 'bait and switch' them. Some people emailed me thinking I worked for Google and that it was nasty how Google was taking something so valuable away from teachers.
Then, the first person subscribed to FormRecycler. Another email came in thanking me for adding features that they asked for previously. The Stripe app on my phone sends me a notification when someone subscribes and there is such elation from seeing that notification. The fact that I took an idea and turned it into something tangible, something valuable, something that other people are willing to pay me to use! That was awesome.
That happened 153 times from April 1 when it launched to the end of the school year in early June! (In fact it just happened as I was writing this blog post!!)
I spent a ton of my weekends and holiday time drawing up a roadmap for FormRecycler and getting a ton of ideas. I implemented a bunch of new updates based on feedback from users.
Then the days before ISTE 2019 in late June, Google announced they were going to incorporate the ability to Import questions from your Forms soon. I was devastated. Seriously, NOW they were going to implement it!?! If it had been a year earlier it would have hurt but not as much. The hundreds of hours I spent upgrading FormRecycler were going to be worthless. I just got a bit nauseous as I typed that still. It hurt. It still hurts.
It hurt more when I played with their native functionality and saw it was faster (as it should be).
It hurt when I saw they could also import embedded images (I had to hack out a crazy solution with XMLs of public form and a Chrome Extension as Google doesn't expose that method in their API).
It hurt when I saw they would import the correct answer (something on my roadmap that I would need to use a Chrome Extension to do or wait for Google to expose the API).
It hurt to read their release documentation and specifically not mention that it was possible with FormRecycler that the only way to do it previously was manually.
But what hurt the most is that their UI and user experience was so similar to FormRecycler. Even the Select All at the top and the checkboxes. Granted that was probably the most intuitive way to do it, so it shouldn't be surprising. But it felt so similar that it hurt. (I still like that FormRecycler gives a bit more detail like letting you see what the options are and what the Grid column and row headings are). It felt like all the work I had done was just for them to say, 'Hey thanks, we are going to take all your work and put it in our product'...except there was no thanks.
FormRecycler question selection view
Native Google Form import question view
Now I know this is only my perspective. Their development team is only focused on their roadmap, its probable they weren't even aware of FormRecycler existing. But that rationale still doesn't fix the hurt.
</rant>
So why did I write about this today? Well mostly it is for myself (as is most of this blog :). It was cathartic to share the story and put it down in words. But I was reminded about it when listening to one of my favorite podcasts: Shukes And Giff. You should definitely give it a go, they are awesome!
I love their Podcast as I always learn something and they are both amazing people. (And I am ashamed to admit, I find their jokes funny...I literally laughed out loud at the fish joke yesterday).
I was listening to the latest episode and Kim started talking about this new, amazing Forms feature...it was like someone stuck a screwdriver in my ribs. Really painful, kinda too my breath away, I was getting a bit dizzy, then realized it was probably only about 10% or 1% as painful as getting stabbed by a screwdriver...but as a math teacher I love hyperbolas (apologies for the painful math pun there).
Then...Kim started to talk about FormRecycler and I was so touched. She mentioned about how impactful it must have been in integrating that feature natively. Her and Giff both talked about me in such glowing terms I couldn't keep it together anymore. I was glad that no one walked by my office at that time as they would have seen me ugly crying.
Thank you Kim and thank you Jen!
Secondly, I had an email from a person who bought a FormRecycler license a few days ago. They used FormRecycler to recycle almost 200 questions just after buying the license. Then they emailed me and asked for a refund since they just found out Google Forms does this natively, for free.
That is where my dilemma lies as a businessperson. Should I refund them? They paid me $24 to use FormRecycler for a license for the next year and used it. I assume it saved them time. At some point afterwards, they learned about the free functionality. I now work for myself full-time developing apps. My ability to buy food and pay rent and live is derived from revenue. I currently have monetized FormRecycler and FormCreator with some other apps on the way.
I refunded them. Why? Maybe I am not ruthless enough. I could justify that they used it and I plan on improving it over the next year. But I can't guarantee that. I do plan on implementing some roadmap ideas and want to reward those people who are supporting me with their license. However since Google is now giving away a version of FormRecycler for free, I need to make money on my other apps. So I have to focus my attention on those avenues instead of focusing on FormRecycler features. That is not good for the end users. I also do empathize with their point of view, why did they have to pay for something that is free in other channels?
My initial response was you paid for it, you used it, it worked, why should I refund you?
At my core, I don't want to be evil. Actually I want to come from a place of innocence. I felt like it was the right thing to do. It is the reaction I would have wanted if I was that person. I am not a big corporation. I am a person responding to another person. I want them to feel like the product I make is worthwhile and valuable. If they don't feel like that I will refund them. I feel like we are a team, with my apps helping to make them more productive. (Although I do want to prove them wrong, show them it will be valuable and then charge them 10x that if they want to come back...but I won't :)
Will Google continue to develop down that track? Maybe. Probably not though. So that is a lose-lose proposition overall. Yes, people can use the feature for free now. They could with FormRecycler with a generous (in my opinion) weekly quota. Yes, it is in the menu so it is more obvious. But Google could do more co-marketing for the 3rd party developers who are making Add-ons that extend their ecosystem, which in turn makes it more helpful for users.
Google is implementing some more strict developer usage of their APIs. This is a good thing, data privacy and security are great. I think they should be more in focus, especially in education. Currently if you use some Gmail APIs you need to undergo a 3rd party security review where the developer needs to pay $15,000-$75,000 to be able to publish Add-ons that use those scopes. That will impact developers like myself and also in turn reduce the free Add-on offerings. So that is not a great thing overall for users. I am not against the security review, mainly disappointed that it will impact free Add-ons. So GSuite users should get used to the fact that they will need to start paying for Add-ons. There will be Add-ons that they are currently using this school year that will either stop working or users will need to pay for to continue to use them.
So was it worthless for me? Was my time wasted?
No.
I learned a ton.
I now have code that I can implement to monetize any Add-on, which I have with FormCreator.
I learned to be a bit more business focused and put a lower quota on FormCreator.
I expanded my brainstorming to think of other ways to focus my time other than FormRecycler.
I learned that I can't focus on only developing for GSuite because if I am playing in Google's backyard, they can also develop it into their own ecosystem on their own.
I learned how to grieve a product.
I learned to be a bit more empathetic to end users.
I learned how I want to be as a business and still want to be people-focused and not evil.
I learned that it is good to share (at least for my personal growth) and that others are aware of it and support me!
I learned that I can't fully focus on Education apps, which is a bit sad, because of the impending need to monetize a majority of my work.
I learned that I am resilient and will keep moving forward.
I learned that I just need to out-innovate Google and other developers who put out competing Add-ons.
If you read here to the end, thanks! Lemme know and I will give you a high five!
October 7
My goal is to be transparent about the processes of publishing my apps. I am in the process of publishing another app, you will see some crumbs populate this site as I need to have some assets for required bits in the publishing process. When it is fully ready I will share more about what it does, so realize it is not a finished documentation process yet :)
I am making a Chrome Extension that requires a Google Oauth (this is the Google Sign-in button for apps). In order to allow developers to use sensitive or restricted Google APIs, they need to go through an Oauth verification and in some cases a 3rd party security review.
Publishing an Add-on to the GSuite Marketplace also requires the Oauth Verification so I have been through the process 3 times already (FormCreator, FormRecycler, and SlidesTranslator).
Where do you start?
In the Google Cloud Project associated with your app. You can get there from your Add-on if you are coding in Google Apps Script or directly at https://console.cloud.google.com/apis?
(You will also need to enable the APIs you want to use and create some credentials to use as a developer, but that will be a different post)
The Oauth Consent Screen is an option in the left sidebar. Fill in the details and add the scope you want to have the users have access to.
You will need to have detailed information on your authorized domain website (I don't remember specifically what I had to do to get it authorized in the first place...maybe nothing?) that shows what the permissions are that are needed and specifically what you will use them for. Not only is that a helpful thing for users, but overall better for data security and transparency.
You also will need to describe what you will be using the permissions for in your app in the Verification form.
Until you have the Oauth Verification you will be limited to the number of users that can install and use your app. There is a maximum of 100 users until the Oauth is verified. Additionally, those users will need to bypass a really scary warning in the authorization window.
In my experience the verification team gets back to you within a day or two and generally will need some more information. Sometimes a video screencast showing the verification is needed.
Currently I am on the stage where they contacted me to get more info and you can see the information I have publicly given them for my Slides Pro app here. I will keep you posted!
Oauth Verification Form
Unverified app warning before Oauth Verification
Email notification from Oauth Verification Team
October 1, 2019
The more experienced a math teacher I was, the more I was comfortable in exploring my flaws and inherent bias built up over the years (more on those for a different post). As a relatively new coder I love the power of code and teaching code...especially as I observed power dynamics from the students side. My best coding students were generally young ladies but didn't feel like they belonged as coders, even though the results showed otherwise. They perceived that the boys were better since they were more confident...but the code didn't care. It just executed and gave the result. Instantly showing whether the goal was achieved or not. The code didn't care about the attributes of the person creating it. This is why we need to teach coding at an earlier age and to all groups of people. Code doesn't judge or stereotype, it just runs and works or doesn't.
Code doesn't care...
how long you have been coding.
about your race.
whether you had breakfast this morning.
if your preferred pronoun is he, she, or they.
how emphatically you give your answer.
your body language.
your tone.
how concise your response is.
your prior knowledge.
if you copied your code from Stack Overflow.
if you asked for help previously.
how long you have been writing it.
how many times you ran the code before.
how many times it failed before.
whether your response is elegant.
if you used the latest framework.
how popular you perceive you are.
if you own your computer.
the type of computer it is run on.
September 30, 2019
I ran across this awesome podcast, https://ladybug.dev/episode/teaching-code/, that discusses teaching how to teach people learning to Code. I love the baseline here that these 3 awesome ladies are not formally trained educators and have great insight into being a successful teacher.
A couple of highlights that hit home for me:
Impostor syndrome in the coding aspect. Really important that the coding arena has people who have been coding for 10 years and those that are in their first day -- both are equally curious. We need to take that into account and touch base with everyone periodically.
Knowing what questions to ask. This is the part I struggle with the most when coding. I just struggled for about 2 weeks trying to implement some code using new tools and environments. My code was continually not working and I tried like 10 different approaches. Finally I figured out which question I had and asked for some help. They were super helpful and gave me a quick direction with a link to a specific method in the API. That link helped me realize a different solution that got me up and running.
In the technical conventions vs real world conventions. Sometimes there are esoteric conventions in coding that are not required for the code to run, however if someone else (even your future self) is going to read the code there are probably real-world conventions to work better together.
Technical connections with real-world analogies. Even though there might be a bunch of technical material abound, it doesn't mean there isn't space for your perspective. It only takes a one perspective to give you insight into a connection or something to 'hang your hat on'. I loved the analogy connecting asynchronous programming with ordering food at a restaurant.
The part that hit home the most is that in my mind these are all great ways to teach math as well as coding. There is a big parallel to teaching math and teaching code. I do think that any good teacher can teach code, it takes the ability to connect with students and break down learning skills into ingestable bites. Not all coders can teach, even if they are amazing coders--just like math.
tldr; Go to https://github.com/AutomagicalApps/functionLesson to get a base math lesson on functions using coding to build a Chrome Extension. No coding knowledge required.
Long version:
So as a math teacher who now codes full time, I still see the world through the eyes of a teacher. So many times as I am working on a coding project I think about how awesome 'this' would be as a lesson in a math class. Giving real world examples of a concept is like gold in a math class and I always love to have an actual response to the incessant question of "When will I ever have to use this in real life?".
<aside> My younger teacher self hated that question and in retrospect would give the most annoying, glib answer.
Student 1: When will we ever use $(insertMathConcept) in real life/job/ever?
Mr. McGowan: Well lets see, your job right now is to be a student and to be successful in that job you need to pass my class. $(insertMathConcept) will be on the test and passing the test is a requirement to passing the class. So you will use it to pass the class. Hence, it will be one of the most important things you will need in life to be successful.
Narrator: UGH. Mr. McGowan is such a smug, pompous $(insertCurseWord).
</end aside>
As I was building a Chrome Extension I was thinking that this would be a great example to update my old analogy for functions. I used to use an airport/airplane example where all the people (input or domain values x) got on a plane (function, flight f) and ended up a the same airport (output value f(x) ). It worked great to talk about function composition as flights with connections in a 3rd airport. This could yield x gets on flight f (the f(x)) and ends up at a layover airport and takes a second flight (h) and ends up at the destination (function composition of h(f(x))). I also liked the symmetry/visual component of x value being inside of f and then the output f(x) getting on the connecting flight h and being shown in h(f(x)).
This also has some built in biases that I now understand a bit more. Not all students will have flown on a plane or understand the concept of a layover or connecting flights. Without a concrete connection to the example it just becomes an abstraction of an abstract concept...the inverse of concrete.
The new example I was thinking of is the browser. All students understand the concept of typing in a URL and ending up at that webpage. Sometimes they might click a link on that page and end at another page (hence the function composition connection). As I was building a Chrome extension I was thinking it would be fun to have the students code up a Chrome Extension and understand how Chrome uses functions to work under the hood and to allow them to expand it, personalize it, and have fun coding as well. The best part about coding and relating to math in my estimation (no pun intended) is the immediate feedback (the code runs or more likely, does not run) and the iterative process of problem solving to try to get it to work. That is the skill that I want students to leave with after their time in my math class. The underlying math concepts are just the vehicle in which they can explore that grit and develop their problem solving skills, figuring out which tools they have at their disposal, determining what the end goal actually is and deciphering on their own which tools to use to get there and figure out if they actually arrived at the intended end goal.
That process is coding. That is what I do all day now. I work on projects like that and need to learn the bits that will get me there.
So how can you use this lesson in your class?
First a caveat: I am not really good at detailed lesson planning, it was the thing I hated most (or 2nd most behind pointless meetings) about teaching. I would develop a skeletal plan, have a general understanding of the problems/concepts I wanted to cover and then see how the class unfolded depending on the class that day. It worked for me. It does not work for everybody (or in the case of my lesson plans, probably nobody as I would omit so much important details that were located in my head). I always say that each teacher is like an artist and has their own artistic flair that they import onto the lesson/class. Each teacher engages with students in different ways and that is why each teacher will teach a class differently, even with the same lesson plan regardless of detail.
OK, caveat out of the way. Here is the skeletal lesson plan. I planned it so you as the teacher will need no knowledge of how to code, nor will your students need beforehand...but hopefully you all will afterwards :)
-1. Take a deep breath, you got this. That code will look funky, you won't know the answers to all the students questions. You will feel uncomfortable. That is good. You will be releasing the power of being the knowledge holder in the room. That can be scary. Breathe. Do your favorite Power Pose (I like the Wonder Woman and the Victory V).
0. Go to https://github.com/AutomagicalApps/functionLesson which is where I hosted the folder of files.
1. Download the folder
2. Unzip the downloaded folder and know where it went (On a Chromebook you can click on the .zip file and then just drag the regular folder to the Downloads and it will copy over)
3. Go to your Chrome Extensions (you can type chrome://extensions/ in the Chrome URL bar)
4. Toggle on Developer Mode
5. Click Load Unpacked button
6. Choose the folder you downloaded (make sure it is not still a .zip file as Chrome doesn't like that, it won't let you choose the .zip folder)
7. Open a new tab or refresh the current one
8. Click the icon button for this Chrome Extension
9. Watch the magic happen!
So now you have a Chrome Extension that will open up https://www.google.com when you click the icon.
Troubleshooting (A non-exhaustive list of things that can go wrong):
The internet might go down and this lesson will be worthless, have a backup lesson plan.
Students might not have access to run Chrome Extensions. Test this out with a student account or student device on your school network first. Might need to talk to the IT people. (Hopefully you will not have to do this...)
Students might not have access to the Developer Mode in Chrome. Students might not have access to run Chrome Extensions. Might need to talk to the IT people. Tell them this is an awesome application of the IT skills they are developing and it is a great ROI for those devices your district spent so much money on (Hopefully you will not have to do this...)
Github might be blocked on your domain. Might need to talk to the IT people. (Hopefully you will not have to do this...)
Student device might die and they don't have a charger. Have them work with another student in pairs.
You only have a few laptops/Chromebooks. No problem, have them work in groups and refer to your group working norms (I know you already talked about them, but they might need a reminder/refresher/development ;)
Chrome might have updated since I posted this and breaks the template example (This is possible but unlikely as I plan to take down the post if it breaks or update the code to get it working again).
Extensions (that will need you to touch the code and alter it):
1. Make it open up a different URL when you click the Icon
2. Can you make it open more than 1 tab with the same URL when you click the icon? 2 different URLs?
3. Make it go to a webpage that you type in somewhere. (A possible solution would be to add a popup.html file with a textarea and a button. The textarea could be where you type the url and the button would execute it. You would need to add a "default_popup": popup.html property to the browser action part in the manifest.json as per here. This popup will override the action when you click the icon in the Chrome bar. It will now popup the popup.html file. You will also need to add the background.js script tag to that html. )
Wow. We really jumped the shark there on that 3rd extension step :) Feel free to contact me for more info on the solutions or use your Google-fu.
My last post talked about how I was struggling. Realize that I understand we all struggle and each of us have our own path, obstacles to overcome, and individual struggles. I am not trying to relate the entrepreneur struggle and my personal path with others that need to deal with oppression, racism, inequity, sexism, bullying, harassment, and many other horrible things! This is a first-world problem that as white cis-male born in the United States to a family of educators that I am lucky to deal with it. I understand that...somewhat. I don't know what your obstacles are and I can't share your story...but I can share mine and the strategies I use to navigate them.
Mindfulness is at the heart of my journey now. Generally I am an overly optimistic person. I remember times in college where I would say (and genuinely in my naivete, believed) that life is too short to be angry. Ignoring anger and labeling certain emotions as bad are not the way to thrive in life. Thich Nhat Hanh's amazing book Anger was really a seminal book for my growth. Tapping into that anger and culturing and soothing it as opposed to letting it fester is a wonderful thing. Approaching each conversation through honesty and not looking into ulterior motives in other people is also a breath of fresh air. As a child there were times I felt taken advantage of (only in an achievement sense--not in any way related to trauma) and navigating collaboration is something I am currently working on. Finding the subtle duality of self and team is a tricky balance for me. My greatest athletic memories come from team success and sharing success with others is much more enjoyable!
So what actions do I take to thrive?
Journaling. Keeping a personal journal is great for me to get my thoughts down on paper and having them materialize is a much better way to deal with them than having the conversations in my head.
Silent Meditation. Currently I am loving silent meditation to calm my mind and allow the thoughts to fall by the wayside. I usually get some clarity on the root issue which is generally not the initial thing that was making me angry or frustrated. Going a little deeper and taking time so I don't 'surface skim' is something I am working on and trying to break habits that have formed over 42 years. Meditation is hard at first. I remember the first sessions I did in Thailand and I couldn't sit still and focus on my breath and thought it was stupid. (as my amazing wife Deanna says though: if you think something is stupid or boring it really means you don't understand or it is too difficult--great advice for dealing with misbehavior in class)
Music: Music helps me focus and allows my mind to fall to the background and let my heart take over, which clears the way for the meditation to become prominent. Currently I love the Good Vibes - Binaural Beats channel on Youtube. Amazing soundtracks to work to and stay focused as well!
Motivational Videos: Sometimes you need a quick jolt to get you going and nothing works better than a great espresso...I mean Jason Silva's amazing Shots of Awe. Wow, the videos are so amazing and can transcend to other states in just a few minutes! They are like instant goose bumps and a great way to progress towards working on crying when tapping into your emotions :) Can you believe he does them in 1 shot with no editing on those
Power Poses: I love the thoughts detailed in Amy Cuddy's TEDtalk on Power Poses and employ them whenever I have an important meeting or presentation coming up. I love the feeling of standing in my own power! These physical motions help me get grounded in my own power and prepare me to speak my own truth.
Friendship: Talking with someone else is great to bring levity to my situation and outside of my own head. Also this usually comes with coffee or some other ritual of daily life that can bring me out of that track. Find someone in real life to converse with or via online modes. It can even be asynchronous with a Twitter chat or some other discussion area. Connecting with people about my passion really helps fill my cup.
Acknowledgement. Sometimes telling someone else I appreciate them or saying thanks is huge for me. Gratitude is amazing, especially as it is done without any expectation of reaction or reciprocation.
I wouldn't have gone as deep down this path on my journey without my amazing wife. My life is so much deeper and rich as a result of things we have done in life, many times taking the road less traveled. Actively seeking opportunities for growth can sometimes seem daunting or something to put off for another day when you have more time or are feeling better. But actually, those are the times when I feel it works the best. In a super stressful teaching day, taking 2 minutes for a power pose and a quick 3 minute silent meditation reset me when I had no other breaks. 5 minutes of magic!
September 24, 2019
As you can see I skipped another few days blogging. In today's Insta & Facebook culture where what is shared is curated to show perfection, it is hard to share when you struggle. I have been tangling with some tricky code and getting bogged down with that instead of blogging and Tweeting. But these are exactly the days I need to blog or share, and more importantly ask for help.
It was awesome to get a Twitter DM from one of my friends with a short message asking "Are you OK?". So appreciative of that support!
It made me realize that someone is reading these and more importantly people care about me. My family is so amazing and awesome, but honestly they are so over me talking about work...which is part of the reason I blog. To organize thoughts for myself and people who might care. Like Sam Altman from Y Combinator says, "it is better to build something a small number of users love, than a large number of users like". I feel like this is the same approach I have with people now too. (The math teacher in me loves how Sam relates the area under the curve--such an awesome relation to a mathematical integral!)
Self-care is a big issue in teaching as it can be an exhausting job requiring your heart and soul just to survive through the day. As teaching is really the only job I ever had before this software development thing, it is the basis that I try to relate everything back to and it really hit home that being an entrepreneur is so similar to teaching. As a solo founder, there are many times I look at my startup like I used to look at my classroom. I was solely responsible for the learning in that room and what went on outside the classroom didn't impact what went on in my room...boy was I so wrong (and ignorant & pompous)!
Once I realized that observing other teachers, learning from their perspective on how to teach a lesson, and sharing my perspective made me a better teacher than my world was forever changed. Not only for me but for my students as well...taking other perspectives into account, especially their students' is the biggest tip I have for new teachers--and a great one for Product Design and figuring out Product/Market fit.
The paradigm that everyone else has their shit together and I was the only one overwhelmed that my lesson planning was not enough was keeping me from loving teacher. It was that feeling that everyone else was doing it better, that other people cared more, that other people were thriving that was keeping me from sharing. Once I realized that everyone has lessons that fall flat on their face, or days that want to make them go cry in their car in the parking lot, or those days that make you want to walk away that all of this stress is not worth it...that was freedom.
This is why I want to share what I have been up to for the last week. The specifics don't matter but I was having a tough time getting some code to work as I was learning a new framework. I was spending entire days not getting the code to run as I thought it should. Reading the API documentation was not helping and it felt like I was missing an integral part. StackOverflow wasn't exactly answering my questions as they weren't using the same quirky platform or they were using different libraries or languages. I would do a Google search and Google would show me I already read the top results yesterday...and they obviously didn't help.
I was struggling so much I felt like I didn't even know the question I was trying to ask. Which by the way is generally the hardest part about coding and I think the greatest parallel to why computational thinking is so important to learn today...figure out how to learn in this age of so much information. So expect some disjointed blog posts this week about my struggle and I hope to share some of the things I do to brighten my day or keep me going :)
September 19, 2019
I want to talk about something I feel like is Taboo in the EdTech space, paying for an app. It really irritates me when teachers want to find a free alternative to a good product. Yes, I am biased as now I sell apps. However, I try to let my users create items for free and they just need to pay if they want to use it more. I think that is a fair proposition. I also try to gauge the amount of time I am saving teachers relative to the cost.
Yes, I understand that as teachers your budgets are stretched thin. My wife and I were both teachers for many years and always spent tons of our own money on our supplies, classrooms, and students. And that doesn't make it right! It is terrible that the state of public education in America is such that it is not valued enough to be properly funded. There are tons of issues of inequity that I can't address in a blog post or even comprehend from everyone's perspective.
But here is my food for thought. How long are you taking to find that free tool? How much time does it take for you to find the 5 free tools that will do what 1 paid tool will do? If the time value isn't giving you the ROI (return on investment, not the Republic of Ireland) that you need, it is worth it for you to use the free tools.
What happens when that free tool doesn't exist anymore though because they ran out of funding? Or worse, how are they making money from your data?
Here is a great example from the amazing John Stevens (I hope you don't mind me using your tweet in my blog!). John has amazing resources that he puts out there for the world to share, using his time and creating amazing value for other educators. I think the creator culture is progressing and will disrupt education over the course of the next 5 years. It has to. I know I will support John. I plan on incorporating some support routes and want to share how I do it to empower other educators to create their brand as well in this age of Teaching in the Gig Economy (more coming on that in the near future)!
I know...I skipped a day (actually 2, I backdated that Impostor Syndrome post...). It is really my own accountability and its my blog...so tough :)
September 17, 2019
So over the past 15ish years I have struggled to share publicly and one of the reasons excuses I have learned about was Impostor Syndrome. (If you haven't heard about it before, watch the incomparable Sorelle Amore discuss it: https://www.youtube.com/watch?v=TcgLw9Si6Ug...I mean that cinematography and content is so powerful...amazing!)
Be authentic.
Thats it! It finally clicked for me maybe a year ago...but Sorelle describes it much more succinctly than I can...which is one of the parts that I struggle with in sharing (read the anecdote at the bottom about 1 reason that contributed to my impostor syndrome). I even had a hard time posting this blog. I rewrote it about half a dozen times and cut out a bunch of stories :)
I used to get really nervous about speaking at conferences but after a couple dozen, it got easy I understood how it flowed when I was authentic. I read a great quote from someone who said the best TEDtalks are not the one where people scripted out the best dialogue, they are the ones where people had a few points of stories they were going to tell and told them. Just be yourself, let your passion come through and you will be authentic and hence not an impostor!
The reason I wrote this post is not to elicit emotions from others, but to relay that the only person who can make you feel like an impostor is yourself!
[As an aside: I love the tip that Kim Pollishuke and Jen Giffen talked about on the awesome Shukes&Giff podcast (Give it a go!) about watching Youtube videos at 2x speed!]
<anecdote warning='Personal anecdote coming up. Stop reading and come back tomorrow to avoid it;'>
I am verbose in conversation and text, I love to talk (which is one reason I became a teacher, the other reasons are too long for hear and would be a blog post in itself) and can go on and on. That is why it was is hard for me to blog...the feeling that I am not fully communicating what I want to share. Actually, and more deeply, it is the idea that what I have to say no one really wants to listen to.
I have done a lot of work in this area, with journaling, meditation, reflection, conversations with people, and many other people who support me in life (like my amazing wife Deanna and daughter Mele). Part of this stems from where I grew up: West Virginia. If you are some of the international people out there and only know of West Virginia through the John Denver song (which incidentally was written in Maryland and mistakenly thought it was WV...now the rest of my family who still live in/near WV will be cursing me for that blasphemy :), WV ranks as the best or near best in the nation for lots of things...like highest obesity rates for adults, highest poverty rate, and most un-educated...all the things you don't want to be known for.
Because of these factors, I always say it is a great place to be from.
OK...I am getting around to it...despite all of those things, I had an OK education experience and a pretty happy childhood and a great family life. I grew up in a small, rural college town and people are generally really nice. The thing that I identified with though was that need to be more than, that being good locally was never enough, that I needed to think on a greater scale. These were not ideas that were drilled into me directly though, I think I just absorbed them subconsciously.
I think it all boils down to 1 point. West Virginia is the only state that has a directional prefix that doesn't have a complimentary state. For example, there is a North Dakota and a South Dakota, North Carolina & South Carolina, West Virginia & East Virginia. Truly by definition, if it needs additional clarification it is the inferior one. I still encounter people who think I am from Virginia totally ignoring the West part...there is no greater pet peeve I have than if you asked me how my trip to visit my family in Virginia went.
There is a lot more that I have resolved from that time and the more I travel and discuss experiences with others, the more I expose or peel back parts of the hurt in my soul that needs some loving.
I get that lots of people have varied experiences or obstacles that they need to overcome. Mine was all about perception, just the thought that I wasn't valuable enough to share my ideas and now I know that is not true...but it did take me something like 40 years to realize that.
Thanks for reading to the end!
</anectode>
September 16, 2019
This one is for my EdTech peeps with a nod to the entrepreneurs at the end.
I just update FormCreator and want to highlight some of the features that were updated.
New Setup Sheet functionality. There are now 2 options to setup your sheet, 1 for a Form Quiz with Feedback options and 1 without feedback. In both options, I also create some sample questions as well to give you a head start.
New question sample inserts from the menu. There can be some tricky items that need to be added to get the question created as you want and also to know about some of the advanced capabilities, like inserting embedded images.
Entrepreneurs: In yesterday's post about pricing I talked about changing the quota and making FormCreator more compelling to users. The update is focused on features that customers gave me as feedback and I wanted to help streamline their workflow process. The new setup sheet comes prebuilt with questions to help give the users an understanding of what FormCreator can do more quickly (hopefully to bring them closer to that Magic Moment referenced by Kevin Hale.
After they have some questions in there they can add ones that have specific structures and parameters from the menu. Reducing the strain of button clicking in the Forms UI saves them time if they are creating multiple items and working through the keyboard can be faster also. We will see if that helps with the conversion rate!
This one is geared towards the entrepreneurs, but I think it has value for the educators as well to see my thought process. One of the difficult parts of shipping a product is finding the right pricing. I listen to a ton of podcasts on Startups, some of my favorites are:
Gimlet's Startup (follow it up with The Pitch and you will thank me later!)
Reid Hoffman's Masters of Scale
How I Built This with Guy Roz (shoutout to Jen Giffen for turning me onto HIBT!)
These are great to give motivation for success and high level topics for starting a tech company and building it. Definitely give them a listen, but the most recent one I have been listening to has great pertinent topics:
Y Combinator Startup School Podcast and also the videos on Youtube as well. These 2 episodes from Kevin Hale about Conversion and Pricing from was really pertinent to me and impacted how I thought about pricing.
One of the bits that I do is give a free quota of questions created by FormCreator per week and then to get unlimited creations you need to buy a yearly premium license. So there are 2 variables in play here for the pricing, cost and quota. I want to optimize these 2 values to get the most revenue. Essentially I want to get the most conversions to premium. There are a few ways to increase this number, get a higher conversion percentage from my current users or increasing the number of users. I am testing out a new quota level with the update I released today, reducing it from 50 questions per week to 30 questions per week.
So why did I choose this number? I have Google Analytics on the users of FormCreator to know how many questions they insert (the Analytics are anonymized so I don't know who the users are). I had a percentage that were continuing to use the full free quota weekly, reducing this quota will either cause them to convert to premium or change their behavior. This might be that they just leave and never come back. That would be unfortunate and as a former educator I understand the dynamics at play so it wasn't a move I took lightly. Continuing to update the product to make it more compelling to use will help counter them leaving. We will see if the conversion rate increases or if I am saturating my early adopters as per what Kevin was referencing in the Conversion talk.
In a nutshell, I want FormCreator to be compelling for users to continue to come back and find value in using it and eventually buy the license.
September 14, 2019
Great question! I plan on sharing content that will be valuable to a couple groups of people.
My EdTech Peeps. This is the arena my passion has been living in since the millennium rolled over. I have been delving into new realms the past 4 years but this is still my default wheelhouse. Especially Google's GSuite...so many of my ideas are geared towards optimizing my time as a teacher in GSuite. (Which is ironic since I haven't had a classroom for 4 years now...that is like a whole class of high schoolers graduating!). I will unashamedly be talking about the Add-ons I create as well as Chrome Extensions and other useful tools.
Digital Nomads. I spent the past 3 years as a Product Manager for an awesome tech company developing the app I sold to them. When I sold it I was just finishing up my year teaching in Chile and we planned on heading back to the US after being abroad since 2009 in Taiwan, Singapore, and then Chile. That was the summer of 2016 and the US seemed like a foreign place to us. We tried to find a place to live...checking out Colorado, California, Hawaii, Austin, Portland ME, and then after the election it just didn't seem like a place where we fit. So we spent the next 18 months figuring out where in the world to live. It was the first time that we didn't have to adhere to the school days, school calendar, or even location. As long as I had fast internet and was able to make a daily standup meeting (which sometimes was the middle of the night like when we were in Bali & Australia), we could be location independent. See the map of our travels and I want to share about how we fared as a family (we started when my daughter was about 2 1/2).
Entrepreneurs. Since I started developing g(Math) and it started to get more and more users back in 2014, I have been consuming as much information as I can about startups, entrepreneurship, coding, and all things that this arena entails. I will share my process, what I have learned and are learning, what I am listening to and reading about, and any insights I get along the way.
Other stuff. I will try to minimize this area as I tend to ramble on about tangential subjects and I plan on creating some arena for more personal stuff...but it is my blog so my personal bits will show up here from time to time. I do consume a lot of information on mindfulness so that will seep into my post. I also use the word awesome a lot. I embrace that so...be warned. Also, I hope to be transparent about the times when I might not be so awesome and the ways I deal with that...so hopefully you will all stay tuned!
My travel as a digital nomad (slomad) -- from the awesome nomadlist.com
September 13, 2019
So how do you plan to survive, like pay rent and eat? That is the big question that random (ok, not mathematically random) people ask me. I have a strategy that will employ a few different approaches.
Monetizing some of the Add-ons that I have built. Currently FormRecycler and FormCreator have Premium plans. FormRecycler was ramping up near the end of the school year...until Google released the same functionality natively in Forms :( Feel free to support me by using those Add-ons (and buying the unlimited plans ;) to be more productive, save time, and amplify your teaching! I developed those so I could be more lazy efficient as a teacher.
Creating content. As my friend Alice says, I have valuable ideas that I need to share. I plan on sharing those ideas in a way they can be replicated and valuable (I think). So you will see me start to create on a variety of platforms (like Youtube), in addition to this blog.
Affiliate Links. Yup. But I don't plan on spamming you with clickbait. I have a lot of people ask me what my technical setup is...and I share it with them. I might as well give them the direct link to Amazon and then I get a small percentage out if it, right? Essentially, I have a curated list of products I love and I will share them. Feel free to buy them from my link or not :)
That last point seems like a great segue...so here are some of the items that I use on a daily basis (with the Amazon affiliate links). I have a bigger post planned with some more details on my daily workflow, especially while traveling. All I need is my Chromebook, headphones, and WiFi (preferably fast)!
My working setup packed up
My working setup
I develop/surf/do everything with my Chromebook Pixelbook. I originally started with the Chromebook Pixel Ludicrous Speed when I joined Texthelp 3 years ago and it was awesome! I loved that it used USB-C and I could use the same charger as my phone (meaning 1 less charger to carry around...super helpful for all the travel I did and fitting in on Reddit OneBag...no affiliate link there, just an awesome Reddit community...be careful though as you might find yourself spending hours on cutting down your stuff).
I also love that I CAN do everything with a Chromebook since so many students have them and as so many haters want to say that you can't :)
Yeah, I am one of those people that has 2 monitors everywhere I go now. It took me until about 6 months ago to use a 2nd monitor. Now I can't imagine working without one. My back and neck love me now. I love this TOPOSH External Monitor! Also, I am so much more productive coding/debugging. I did code/create for about 5 years with just a laptop and will say the 2nd monitor is a luxury, but for the price it can't be beat. I love that it works with my Chromebook, doesn't need an external power cord (other than the Chromebook USB-C cable) and has a nice fold up case that is just slightly bigger than my Chromebook case (and is 15.6"!). Also, it comes with all you need to make it work, just plug it in and go!
This Satechi USB-C hub is the glue that holds together my minimal workspace. I plug my USB-C power cable into it, plug that into my Chromebook Pixelbook and then I can plug in any external bits I need. I plug in the external monitor with HDMI, the ethernet cable, it has a few USB plugs which work nice for my Blue Yeti mic, and I also use it to upload pics from an SD card as well. It is super small to just pop into my cable case and away I can go from home office to co-working space.
I love these Plantronics Backbeat Pro 2 headphones! They are super comfortable on my ears and I was able to get replacement earpads when the original ones wore down after 2 years. The noise cancelling is awesome, especially in a loud cafe or co-working space. They are Bluetooth compatible and also have an open setting so I can toggle it on to hear my daughter without needing to take them off. They also collapse down easily for transport by tilting the ears inwards. I tried lots of headphones like Beats and Bose and these were by far my favorite!
September 12, 2019:
Hey all,
So here is the first post that I am putting out in documenting my startup journey. I hope to share information as I travel along this amazing journey. I assume there will be lots of ups and some downs (hopefully more ups than down) and want to try to be as transparent as possible for anyone trying to follow the same dream.
I love the podcast Startup by Gimlet and how they shared their journey to make a startup podcasting company. It was awesome to hear the progress they made as I binge-listened and then to catch up to present day to see that they were a huge success! I hope that this blog and other components will help showcase those and I figure the worst thing that happens is I will be able to have a nice post-mortem dissection of a failed company...but the best part could be an awesome follow-along to a successful company!
My goal this year is to share more. Yeah, that has been my goal since like 2012 (or 2014)...for real go check my old blogger posts…as you can see I do a great OKish job starting something and then not finishing it. This is not the plan here and I figure I can blog about something every day. It might not be valuable to anyone, but it will be valuable to me. Following along the lines of Seth Godin, if I can't find one thing that is important or unique or want to ponder on during the course of the day, then I am not trying hard enough!
So this is nothing new, but this time I have no safety net. I left my job as a Product Manager for EquatIO, have no other income, and need to make it work! I have total optimism that my passion will help my company succeed and I am surrounded by an amazing family that fully supports me. My wife, Deanna, is awesome and totally is behind this crazy journey. My daughter Mele is the inspiration of it all, from creating g(Math) to selling it and now rolling my own startup. She even supplied the company name: Unicorn Magic. Someone is squatting on that domain for like $10,000 and I won’t succumb to the extortion so I publish my apps info and blog here at automagicalapps.com.
My goal is to blog daily and talk about my journey from being a teacher to an entrepreneur. I will also tweet when I post a new blog entry so follow along on my journey at @automagicalapps!