stardance has been extended another month! the new deadline is october 31 :)

You are browsing as a guest. Sign up (or log in) to start making projects!

R10

@R10

Joined May 31st, 2026

  • 32Devlogs
  • 7Projects
  • 0Ships
  • 0Votes
Open comments for this post

4h 29m 31s logged

DEVLOG #8

ㅤ
It’s been a long time since I wrote my last journal and that is because I just didn’t feel like writing a journal. It just seemed like too much work. I was also busy studying so I could not code and journal as frequently but I have made significant changes to my Lead handling ideas and I would like to share them.
ㅤ

LEAD GENERATION CHANGES

Basically, I have decided on a flow where a user can send multiple queries at the same time to generate leads from and choose the number of leads that they want to generate for each query. This would make work faster if a user wants to target a diverse set of businesses.
ㅤ
while generating leads, the user will see 2 options. In the first one, the user will be asked to enter their query. In the second one, the user will be asked to add an upper limit to their search.
ㅤ
There will also be a “+” button at the bottom of each “query box” of “query batch” so that a user can add another query box and mix and match how many leads they want and what queries they want. both questions are required for a query and hence there will be a continue button only when both a re filled. If the user adds a new box then the continue button will again disappear until both of the new questions are filled and so on and so forth.
ㅤ

BATCHES

Every lead generation is now given its own batch. A batch can be managed easily by going to a new “Manage Leads” tab where the user can do all sorts of stuff like view generation history, view all batches, push generated batches to the team, remove batches, break up batches, set deadline on batches, etc.
ㅤ

LEAD PUBLISHING

Earlier, the flow was such that the boss generates the leads and the leads are there for everyone in the team to view immediately. We do not want that. Instead, now the flow is that when the leads are generated, they are only visible to the boss so that they could tune the batch by adding deadlines and stuff. Then, when the boss is ready, they can publish the full batch to the common workspace where all the employees can see the leads and pick them up.
ㅤ

WORKING ON LEADS

once the leads are published, the employees in the team can pick up leads and start working on them. This is the flow that I have decided upon.
ㅤ
Claim Leads -> Work on Claimed leads -> Log outcome of call -> Complete lead
ㅤ
It is as simple as that. As per the endpoints we have /leads/{lead_id}/claim to claim a lead, /leads/{lead_id}/log to make a log for a lead and /leads/{lead_id}/complete to complete a lead. There is also an endpoint /leads/{lead_id}/return which is used to return a claimed lead back to the common pool.
ㅤ

ㅤ
code wise there have been a lot of changes like new lead_batches and call_record tables and a lot more stuff so I won’t go in depth about all that because then the journal would be too long and I honestly do not want to spend much time journaling and I would rather spend more time coding.
ㅤ
While writing this journal, I also thought of a bug for my scraper logic:
ㅤ
Imagine if a user wants 10 leads for dentists in delhi, the user scrapes and the scraper only looks at the first 10 businesses even though there are 124 businesses. Next, the user wants leads for dentists in Delhi again the next day so the user scrapes again. Now, since the scraper does not know if this business already exists in the database, it will just give the same 10 businesses as before and all get marked as duplicate event though we have other 114 businesses. But, they will never be scraped because the search is linear and the scraper has no context of, this lead exists, leave it.
ㅤ
So, I think I will be spending my trying to fix this bug somehow as this is pretty serious.
ㅤ
commit: 45f5e2d4107b23bd4a7609aaf17fd0bafb566bcf

0
0
12
Open comments for this post

2h 56m 11s logged

DEVLOG #7

ㅤ

SCRAPER

Made a few significant changes to the scraper:

  1. Earlier, my scraper was based on the CLI logic where the user will enter their query and then the program will scrape all the businesses for that specific query before asking the user about how many leads they wanted to generate. But, now that I am switching from CLI to web, this logic is broken (even from a CLI perspective this logic was broken). Basically, if there are 124 businesses found for a certain query then the user would have to wait at least 84 seconds (I tested this time and it is not an estimation) for the whole search process and generation. Now this long wait time is because the program is basically asking the user the limit of leads they want to generate but the point of application of that limit is incorrect. For example, if a user only wants 50 leads, then the program would still go through all the 124 businesses and then only generate 50 leads out of those 124. Thus, all the searching and scrolling through the menu takes time. Whereas, now If we instead make it such that the user inputs an upper limit value to their search all along then the time would be significantly improved. For example, If a user only wants 50 leads out of however many there are, we now don’t try to find all the leads and then apply the limit, we instead apply the limit straight at the searching step and then generate all the found leads. Using the same 124 total leads example, now the scraping and lead generation time is only 33 seconds.

  2. while randomly talking about my project with gemini (and glazing it), I suddenly got a feedback for it out of nowhere. It said “wow, its great that you are using playwright. Make sure to not make new browsers for each user or else your scraper will burst cause of the ram usage”. This completely unexpected feedback really made me think cause that is exactly what I was doing up until now. So, I asked it how to fix it. It told me to create a single browser for the lifetime for the app and for each user, simply make a new browser.context(). Well, I was going to do that but I found out that to do that, I first have to turn my whole playwright script into async. I do remember why I had to do it but if I explain that right now then it would take too much time and would be too boring. The simplest explanation that I can give is that sync runs on multiple threads, so if 2 requests coincide, the data could get merged or damaged. Hence, async is like the ultra time managing chef which works on a single thread but manages all the coming requests so that it works even when it is waiting for another process to happen. So, after doing all of that, I think my scraper will not blow up now. This was a precautionary step more than an immediate necessity but its good to handle it early than to regret not adding it after the project goes live.

/lead/reinstate ENDPOINT:

I also made the reinstate endpoint which acts on duplicate leads. There are 4 specific cases that it looks for:

  1. If user provides a flag value -> reinstate all leads with that flag by clearing the flag and pushing changes.
  2. If user provides a lead ID -> reinstate the lead with that lead ID by clearing the flag and pushing changes.
  3. If none are provided -> reinstate all duplicate leads.

By default, a user cannot pass both flag and lead_id.


Now that all of my basic endpoints are complete with all the tables covered and linked together successfully. I can now move onto the more deeper logic of the program and work on some more features like call records with the ability for the users to mark the status of the call, etc. and other stuff that I have thought of. Also, I made a new frontend.md to store all my fronted ideas as I make the API and ideas.md as I come up with more useful ideas.

commit: 2fbba880236ed9644733666de2cfb4dcacba40cb

0
0
23
Open comments for this post

2h 32m 34s logged

DEVLOG #6

I have been working on the leads route for the past 3 days and this has been a lot of slow progress. I have been coding less and more thinking about the design of how leads are generated. Basically, the 2 endpoints that I have made till now are /leads and /leads/generate-leads.

/leads:

This endpoint is responsible for simply getting all the leads generated for the team. It simply takes the current user, finds their team and query the database to find all the leads for that specific team ID. This was pretty simple to make and there is not much to describe in this.

/leads/generate-leads:

This is the endpoint that took a lot of iteration and design changing to get right. The basic idea that I had before making this endpoint was that I use my existing scraper function to scrape the businesses, then check the database to see if the lead already exists (this is the point which take a lot of time to design) and then either add the lead or not. Now it was simple in theory, but there were a lot of questions like - what is the parameter to check if a lead exists?, If a lead exists then should the newly generated lead just be dropped?, if we drop the lead then what about the case when something about a business genuinely changed like its name or something?, what if the user wants to still act on duplicate leads?, etc.

I will not go in detail about all the failed attempts at designing the structure for lead generation and I will instead just focus on what design I finally decided.

It is basically a flag system which flags duplicate leads and the type of duplicate.

  1. we make sure that the user requesting for lead generation is a manager of their team and not an employee (cause employees don’t get to generate leads for the team).

  2. we use the scraper to generate the leads.

  3. we loop through the newly generated leads. In each pass, we query the database to find if there is an existing lead. Now, I realized that a lead is basically just a phone number. Thus, if a phone number for that specific team already exists in the table then we have a duplicate lead. If we do find a duplicate lead then we move onto the Lead Sorting Logic. Else, we simply add the lead to the table as a fresh lead.

  4. Finally we commit all the changes to the leads table after the loop completes.

Lead Sorting Logic

  1. If name and website changed -> Flag = 0
  2. If only name changed -> Flag = 1
  3. If only website changed -> Flag = 2
  4. if completely duplicate (nothing changed) -> flag = 3

This sorting makes it easy for the UI to display duplicate leads to the user and I am planning on adding a feature where the user can decide if they want to reinstate the duplicate leads for assigning quota.


Next, I will be working on some bugs that I think are in my current logic. Right now, I am asking the user to prematurely enter the number of leads they want to generate without knowing how many businesses were even scraped for their query. For example, if someone wants 100 leads for their query but we could only scrape 80 then there will be an error according to the current logic. Therefore, I am thinking to split the lead generation into 2 parts. First the scraping part and then the generating part. For that, I simply need to restructure my single scraper function into 2 separate functions. Then I will call the 2 functions one by one in 2 endpoints.

0
0
3
Open comments for this post

1h 44m 33s logged

DEVLOG #5

I found out about JSON Web Tokens (JWT) and how they are used to help in user authentication. I learned more about JWT and found out about the python library Pyjwt. What I made is basically this:

  • new auth_utils.py file which contains the following functions: create_access_token, decode_token, get_current_user.
  • Reformed auth routes’ response to carry the JWT inside the response body during the signup/login.
  • .env file with a secret key for the JWT.

AUTHENTICATION LOGIC:

The basic logic behind the JWT is that we get the access token and provide every user with their own unique access token at login and signup. This token is then stored in the LoclStorage (for now this is the plan but this being a fronted thing, it is subject to changes) but I am currently wondering about the security of the token being stored in the LocalStorage because a simple JS script can retrieve the token. Also, given that I am not utilizing a refresh token for this version of the program and the 30 day expiration of the access token, the token getting leaked is a big safety hazard so I am looking at utilizing httpOnly cookies instead which cannot be accessed by any rogue JS script running in the browser and would insert the token inside the request header automatically without any backend side JS script having to look into LocalStorage first.
Next, we have a function whose sole job is to authenticate the token and then return the user from the database. This function would be called by all the endpoints the user has access to so that we first authenticate the session of the user before providing the user with any data. This means that if you are on /home and you want to go to /leads, /leads will first authenticate the token given to you and only then will you be able to access that endpoint.

HOW IT WORKS:

  • create_access_token: takes in the user id and uses it along with the secret key to encode the JWT. The payload consists of the user id and the expiration which is set to 30 days from when the token is issued.
    ㅤㅤㅤㅤㅤ
  • decode_token: simply takes in the token, secret key and the algorithm used for encoding to decode the JWT back into the original payload used during encoding.
    ㅤㅤㅤㅤㅤ
  • get_current_user: This is the function that authenticates the user session. Basically it has 3 jobs:
    1. Use HTTPBearer() to extract the authorization credentials from the Bearer <Authorization> in the request header. Here, the credentials in the header will be the JWT for the user.
    2. Decode the extracted token using decode_token function to get the payload back and handle all the errors like ExpiredSignatureError, InvalidTokenError, etc.
    3. Finally, use the payload to extract the user ID and query the database to find that user and return the user object.

Now, I will be working on making the leads route which finishes off all the current tables that I have made.
ㅤ
commit: 1ad521f0218e9b6c8f9ebe908e01e6a578c78643

0
0
76
Open comments for this post

1h 8m 8s logged

DEVLOG #4

I reformed the Signup API flow and also made the Login endpoint.

The new signup API flow goes something like this:

PAGE-1:

  1. Enter full name
  2. Enter email
  3. set password
  4. Submit button
    when submit button is clicked, we query /users/check-email to check if the account already exists. If account exists, the API simply returns a status_code=400, detail="email taken" else it returns {"available": True}.

PAGE-2:

  1. Set Username
    When submit button is clicked, we query /users/check-username to check if the username is available or not. If username is already taken, the API simply returns a status_code=400, detail="username taken" else it returns {"available": True}

PAGE-3:

  1. Choose if signing up as a business or as an individual.

PAGE-4:

  1. Set team name if applicable.

Finally, we have all the required data and data validation to make a new user so we can POST to /users to make a new user. Now, I had to think about this a bit because what if a there is a scenario that while a user is still making their account, they enter a username and go to the on-boarding step with the team name entering and all that stuff. And meanwhile, another user also enters the same username and creates the account by finishing the on-boarding before the first user who has the same username but did not create the account yet? when the user who is currently on on-boarding finishes all the steps, the server errors if there is no second data validation with all the collected data. Hence, I added validation of username and email in the second step too so that this case is handled correctly.

I also made the simple login endpoint which takes the email and password and validates the user and their hashed password. I am planning to keep the login a single page and hence there are no live validations I need to make. Thus, everything lives in a single /login endpoint.


Next Steps

I am also wondering that in the API response, I do not signify anywhere that if the user is currently logged in or not and I do not know how to keep the user logged in until either they sign out or something else so I need to learn that state management too. I will work on that next.

0
0
11
Open comments for this post

1h 25m 51s logged

DEVLOG #3

Today I worked on just the signup endpoint and the password hashing. I basically made an endpoint which would take all the collected data: full_name, username, email, hashed_password, role, team_name and use it to create team and user on the database. I have successfully implemented the basic idea that I had but it currently has no error handling like duplicate user checking or existing username.

So, what I thought was to keep a single endpoint and do the data validation at the end when the api call is made by querying the database first to check for unique email and username. But, That was not good user flow according to me, and I was looking for something like this:

PAGE-1:

  1. Enter full name
  2. Enter email
  3. set password
  4. Submit button
    Then we will internally check if the email exists or not. If it exists show “account already exists, login instead”. If the email does not exist then move into the next page.

PAGE-2:

  1. Set Username
    Check if username exists. If username already exists, show the error “username already taken” else move onto the next page.

PAGE-3:

  1. Choose if signing up as a business or as an individual.

PAGE-4:

  1. Set team name if applicable.

All the data required for the database entry for user creation is complete so after a few more random onboarding steps, commit all the collected data to the database to make the team and the user.


Basically this is the whole signup flow that I want with the most basic data collected from the user initially. Now what I want it some way to check the validity live on every page and I do not know how to do that. I will need to display the error messages and all through JS though I don’t know if I can also query the database live through JS to do some live validation. I will not learn this FastAPI concept and try to implement it in my API

0
0
18
Open comments for this post

2h 0m 15s logged

DEVLOG #2

Created all the database models along with database.py with the boilerplate code for making database and tables.

Database models that I made:

  1. Team -> id, team_name, created_at
  2. User -> id, full_name, username, email, hashed_password, role, team_id, solo_team_id, created_at
  3. Lead -> id, team_id, name, phone_number, website, rating, created_at

I also made some changes to scraper.py by adding more filtering such that:

  • If business does not have any phone number but has a website, lead is added.
  • If business has a phone number but no website, lead still added.
  • if business does not have any phone number or website, it is basically useless and excluded.

I have not faced any major challenges yet as it has mostly been boilerplate code straight from the docs or simple repetitive code. To be honest, this has been boring. But, now I will be starting with the FastAPI stuff and actually start making the API and I am very excited for that.

0
0
52
Open comments for this post

3h 55m 9s logged

DEVLOG #1

The scraper is something that I had completed a few months back. I made it for my friend’s business. Now, I am trying to expand the scope of this from just a scraper to a full Business platform where a whole team can collaborate on cold-calling with daily quotas and a manager who can view stats about his employees. I also want to make a live chat option to better increase coordination between the team. It is a pretty basic project but a pretty ambitious for me.

Right now, I have completed all the error handling and re-enforcing the scraper logic in the 4 hours that I have spent, to make it ready for a web-UI.

I will now start working on making the actual API and database for my project.

There are 3 basic tables that I have identified:

  1. Teams
  2. Users
  3. Leads

I believe that all other features can build on top of these 3 as these are the basic building blocks. Hence, I will start working on making these right now.

This is my first time working with FastAPI (earlier I had only used Flask) so there will be a learning gap but I have experience with Flask so I think that transitioning would be easier.

0
0
18
Open comments for this post

7h 40m 3s logged

DEVLOG #21

Completed the CLI tool and created binaries for windows and linux using pyinstaller.

Also completed the full Guide page on the website with all the relevant rules, syntax and limitations listed cleanly.

0
0
12
Open comments for this post

1h 12m 17s logged

DEVLOG #20

Completed and wired Unparser

TRY NEW UPDATE

I completed the unparser now with the precedence based approach and I can’t believe how much simpler it is and how bad my initial approach was.

The thing that makes it work is the new needs_paren function which basically does all the precedence based logic of telling if the child needs parenthesis or not. Basically if the child’s precedence is lower than the parent op then we need a parenthesis. For example: if the child is a + node and the parent is a * node then we would need parenthesis on the child. For example:
(x+1) * 3 -> x+1 needed parenthesis.

The main part that made me think a bit was the case when precedence of the child and parent is equal. There are basically 3 cases here:

  1. When op is + or *, the child never needs parenthesis.

  2. When op is - or /, the child only need parenthesis if it is on the right side. For example:
    precedence of + == -, a + b - c -> a+b is on the left side and hence does not needs parenthesis. Whereas, c - (a+b) -> a+b on the right side needs parenthesis because this basically means c - a - b and not c - a + b. Hence, parenthesis is required.

  3. When op is ^, parenthesis is only required when the child is on the left and not when it is on the right. For example:
    a^b^c does not need parenthesis (even though it could be written as a^(b^c)) but, (a^b)^c needs parenthesis because this means a^(b*c) as the powers multiply.

I have also wired in the unparser function to derivative and simplify too so now the result is an expression instead of a tuple.


Now I will update my README.md and explain the working of the unparser and then I will work on adding the guide page to my website.

0
0
59
Open comments for this post

3h 58m 46s logged

DEVLOG #19

Another Setback

I was working on the unparse function today. Basically the idea was simply to recurse through the tree and form the expression as a string. Now, the hard part in this was to decide when to apply parenthesis. Basically, we have to apply parenthesis to any child of the function which has a lower precedence then the current parent op. I did not have this idea as well set in my mind when i was making this function and I just wasted 4 hours today trying to stack up elif cases with or conditions to try to cover every shape.
‎ ‎ ‎
Basically, I was thinking that for *//, there are only 4 base cases:

  1. both children need parenthesis
  2. left needs parenthesis
  3. right needs parenthesis
  4. none need parenthesis
    ‎ ‎ ‎
    I took that as a starting point and then i started to think of cases which would satisfy that and that caused me to build up this or-or-or jargon. I am really pissed.
    ‎ ‎ ‎
    Now I will change my direction and move onto a precedence based approach which checks if the precedence of the child is lesser than the parent op, if yes then parenthesize it and if no then check if precedence is equal, if it is then check for associativity. That is the plan and I hope I don’t mess up this time.
0
0
5
Open comments for this post

4h 36m 47s logged

DEVLOG #18

LIVE PROJECT

I have finally deployed the Version-1 of the project on vercel, check it out at the link above.

I also completed the README for my repo explaining all the features and limitations of the project. Now I will be working on making an unparser to show the users a clean expressions as a result from the calculator instead of AST nodes and I will also add a guide page on the website for the syntax rules and general guide.

0
0
39
Open comments for this post

6h 33m 13s logged

DEVLOG #17

Completed Styling

(would appreciate feedback)
‎ ‎ ‎

Features:

  1. AST generator
  2. AST visualizer (downloadable SVG trees)
  3. Domain calculator
  4. Range Calculator
  5. Derivative calculator
  6. Simplification
    ‎ ‎ ‎

Next steps:

  1. AST back to expression generator because right now all the calculators give the result in terms of AST nodes so i need a reverse-parser which I think would be easy.
  2. Making a simpler bare bones CLI tool for simpler People.
  3. adding a guide page to the website explaining all the limitations and syntax of the calculator.
  4. hosting on my own domain?

That is all that I can think for now.

Right now I have not hosted the website because I am thinking of adding a few more features like user changeable SVG node and line colors, etc.

0
0
34
Open comments for this post

7h 19m 19s logged

DEVLOG #16

More PROGRESS!

  1. completed range.py

  2. tested edge cases with some pretty nasty ones and have decided to leave some limitations like not supporting gif/frac/sec/tan… functions because of their nature.

  3. General Debugging

  4. created all the flask endpoints along with the basic HTML layout of the website and wiring in the JS.

  5. Website is tested and all endpoints are working


Now, I will focus on adding some styling to the website and also making the user experience better.

0
0
17
Open comments for this post

7h 43m 23s logged

DEVLOG #15

Real PROGRESS!

  1. Completed the full differentiation pipeline which is working completely now with all edge cases (that I have tested) handled.
    ‎ ‎ ‎
  2. converted simplify to a standalone file as I noticed that simplify could be used as a general simplification pipeline for ALL generated nodes in my maths suite.
    ‎ ‎ ‎
  3. Created pow_to_div function in simplify to turn negative exponents into division nodes to make the simplification pipeline truly generalized because none of my other algorithms expect a negative exponent.
    ‎ ‎ ‎
  4. A LOT of debugging in domain.py and testing some edge cases.
    ‎ ‎ ‎
  5. Adding support for multiple exclusions instead of single in normalize_domain.
    Earlier: (-∞, -2) ∪ (-2, 2) ∪ (2, ∞)
    Now: R-{-2, 2}
    which is a much cleaner solution
    ‎ ‎

Now I am working on completing range.py and then finally making the website for the full maths suite.
‎ ‎ ‎
I am a bit confused. I am not able choose between flask and FastAPI. If you have read all this then would you also mind sharing your opinion on what should I use in the comments?

0
0
48
Open comments for this post

7h 51m logged

DEVLOG #14

‎ ‎ ‎ ‎ ‎ ‎ ‎
Completed the full simplify_initial pipeline. Handled cases with 0 and 1 and traced a full long recursion by hand to better understand the pattern and make iterative debugging faster. Also handled negative node by simplifying the ('*', '-1', right) node formed so that any coefficients collapse cleanly and the term can form correctly with a negative coefficient.
‎ ‎ ‎ ‎ ‎ ‎

EXAMPLE:-

  • Earlier: x - 3x -> terms = [(1.0, 'x', 1.0), (-1.0, ('*', '3', 'x'), 1.0)]
  • Now: x - 3x -> terms = [(1.0, 'x', 1.0), (-3.0, 'x', 1.0)]
    ‎ ‎ ‎
    Therefore, now merging terms will result in ('*', '-2', 'x')

I pasted my code into claude and asked it to generate me some test cases which it believes would fail and now I am working on debugging them with a mix of hand tracing recursion and simple fixes so the pipeline is almost at its end (I hope).

0
0
36
Open comments for this post

7h 46m 12s logged

DEVLOG #13

‎ ‎ ‎ ‎ ‎
I have completed the basic simplification functions now but, it is not working perfectly and there are still some changes to be made. for example, handling cases where it is multiplied by 0, or when 0 is added, or it is multiplied by 1, etc. so I think it requires a bit more of iterative debugging to catch all of the edge cases. I have formalized the design of simplification into: Flatten -> form_term -> merge_terms -> form_node -> rebuild‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎
which is much better then the previous logic that I had where I was adding more edge cases for handling each case.
‎ ‎ ‎ ‎ ‎
Right now I will be testing the full recursion for a test case to check where it goes wrong right now in the pipeline to fix it.

0
0
16
Open comments for this post

8h 54m 37s logged

STUCK

So basically, since my last devlog, the main feature of the new derivative calculator that I had proudly announced is now coming to bite me. The simplification is so tough. Let me explain you all the turn of events. (Simplification is still not complete)
‎ ‎ ‎ ‎‎ ‎
basically, my initial idea of simplification was just removing all the temporary zeros and ones that were generated by the derivative itself. Then I thought of increasing the initial scope to support some other simplifications like (‘’, ‘2’, (’’, ‘2’, ‘x’)) should be solved to (‘’, ‘4’, ‘x’). I managed to achieve this simplification too but, I found out there are a lot more simplification cases that I need to handle after we get the derivative. for example: x - 3x, which should be simplified to -2x. For that I had to build an approach which would take the coefficient and base then operate on the coefficients
for the same bases according to the operator. Therefore, for x the coeff is 1 and then for 3x the coeff is 3 but that is incorrect. In the case of x-3x, the coefficients should be 1 and -3 so that when i add them i get -2 as the final coefficient for x. To do that, I had to switch all binary subtraction expression and turn them into additive unary negative for op = ‘+’ so that x - 3x turns into x + (-3x). Now, all this actually worked but the main problem was that now the flattened list looks like ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ [‘x’, (’
’, ‘-1’, (‘’, ‘3’, ‘x’))] which means I cannot reliably extract the coefficients now. I first have
to handle the recursive case of flattening the node again, turning (’
’, ‘-1’, (‘’, ‘3’, ‘x’)) to the flattened version
[‘-1’, ‘3’, ‘x’] and then i would have to run it back through combine where it would be formed as calc = -3 and symbols = ‘x’ and then rebuild it as the node (’
’, ‘-3’, ‘x’). Only after that can i actually extract the coefficients and compare the bases of the two expressions which would be 1 and -3 and calculate them according to the op => ‘+’ to finally give -2 as calc and ‘x’ as symbols and then rebuild that again into (‘’, ‘-2’, ‘x’) to solve it.
‎ ‎ ‎ ‎
Now this was just one case for one operator but i need to handle both ‘+’ and ’
’ as the both have associativity and there are other cases for other ops too like x^2/x should just simplify to x. I have already added so much code that I myself feel like the approach is very wrong and the more I build the more edge cases I am adding because right now the amount of if-else handling for specific cases is crazy so I really think that I need to reconsider my approach for simplification. The derivative calculator is taking too much time considering it is an intermediate step but I think it would be worth it because this simplification step is something that I have never done before so I would be learning something anyway.

0
0
15
Open comments for this post

8h 2m 54s logged

Derivative

For finding the range, I am opting for method of differentiation to check intervals. hence, I have made derivative.py for differentiation.
‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎
This is my second derivative calculator. The first one that I built was made completely using string slicing and weird string manipulation and pretty biased logic where everything was stored in the form of a dictionary. To be honest, I was pretty proud of that calculator because I was able to make it just using the knowledge I had, and recursion is not innate (I think) and I was still able to do it so I am proud of it. But, it was no doubt pretty inefficient with a lot of edge cases. Therefore, this time i am making a better calculator using my new AST representation and A LOT more recursion. This calculator will process more functions and it will be able to simplify the derivative too, for example: derivative of 2x^2 will not be displayed as 2*2x, rather it will be correctly displayed as 4x.

0
0
44
Open comments for this post

6h 7m 1s logged

Devlog #10


Completed domain.py

finished coding domain.py and tested about 20 test-cases on it. Completed debugging to finally finish domain calculation and start with Range.

I do not know what else to tell you all as it has been a few days of coding and debugging with different bugs surfacing like incorrect handling of undefined functions, normalizing output, handling union cases correctly, etc.

0
0
9
Loading more…

Followers

Loading…